From c0a275ae877dc6d4d3be3b737527e45d3970cb4f Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Fri, 22 Oct 2021 19:53:23 +0200 Subject: [PATCH] Reimplement legacy logging --- example/pom.xml | 8 +- .../tdlight/client/SimpleTelegramClient.java | 6 -- src/main/java/it/tdlight/common/Init.java | 12 +++ src/main/java/it/tdlight/common/Log.java | 39 ++++++++-- .../it/tdlight/common/NativeClientAccess.java | 12 +++ .../it/tdlight/tdnative/NativeClient.java | 7 +- .../java/it/tdlight/tdnative/NativeLog.java | 74 ++++++------------- 7 files changed, 85 insertions(+), 73 deletions(-) create mode 100644 src/main/java/it/tdlight/common/NativeClientAccess.java diff --git a/example/pom.xml b/example/pom.xml index e2ff18b..37a4b7e 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -26,24 +26,24 @@ it.tdlight tdlight-java - 2.7.8.28 + 2.7.8.29 it.tdlight tdlight-natives-linux-amd64 - 4.0.168 + 4.0.169 it.tdlight tdlight-natives-windows-amd64 - 4.0.168 + 4.0.169 it.tdlight tdlight-natives-osx-amd64 - 4.0.168 + 4.0.169 diff --git a/src/main/java/it/tdlight/client/SimpleTelegramClient.java b/src/main/java/it/tdlight/client/SimpleTelegramClient.java index 69dc166..0776a5c 100644 --- a/src/main/java/it/tdlight/client/SimpleTelegramClient.java +++ b/src/main/java/it/tdlight/client/SimpleTelegramClient.java @@ -34,12 +34,6 @@ public final class SimpleTelegramClient implements Authenticable { } catch (CantLoadLibrary e) { throw new RuntimeException("Can't load native libraries", e); } - try { - //noinspection deprecation - Log.setVerbosityLevel(1); - } catch (Throwable ex) { - LOG.warn("Can't set verbosity level", ex); - } } private final TelegramClient client; diff --git a/src/main/java/it/tdlight/common/Init.java b/src/main/java/it/tdlight/common/Init.java index 5d8b745..76d9169 100644 --- a/src/main/java/it/tdlight/common/Init.java +++ b/src/main/java/it/tdlight/common/Init.java @@ -17,14 +17,21 @@ package it.tdlight.common; +import it.tdlight.client.SimpleTelegramClient; import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.LoadLibrary; +import it.tdlight.jni.TdApi.SetLogVerbosityLevel; +import java.util.concurrent.atomic.AtomicBoolean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Init class to successfully initialize Tdlib */ public final class Init { + public static final Logger LOG = LoggerFactory.getLogger(Init.class); + private static boolean started = false; /** @@ -36,6 +43,11 @@ public final class Init { if (!started) { LoadLibrary.load("tdjni"); ConstructorDetector.init(); + try { + NativeClientAccess.execute(new SetLogVerbosityLevel(2)); + } catch (Throwable ex) { + LOG.error("Can't set verbosity level on startup", ex); + } started = true; } } diff --git a/src/main/java/it/tdlight/common/Log.java b/src/main/java/it/tdlight/common/Log.java index b4fdf3a..21ff73c 100644 --- a/src/main/java/it/tdlight/common/Log.java +++ b/src/main/java/it/tdlight/common/Log.java @@ -1,7 +1,12 @@ package it.tdlight.common; import it.tdlight.jni.TdApi; +import it.tdlight.jni.TdApi.LogStreamDefault; +import it.tdlight.jni.TdApi.LogStreamFile; +import it.tdlight.jni.TdApi.SetLogVerbosityLevel; import it.tdlight.tdnative.NativeLog; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; /** @@ -18,6 +23,24 @@ public final class Log { } } + private static final AtomicReference LOG_FILE_PATH = new AtomicReference<>(null); + private static final AtomicLong LOG_MAX_FILE_SIZE = new AtomicLong(10 * 1024 * 1024); + + private static boolean updateLog() { + try { + String path = LOG_FILE_PATH.get(); + long maxSize = LOG_MAX_FILE_SIZE.get(); + if (path == null) { + NativeClientAccess.execute(new TdApi.SetLogStream(new LogStreamDefault())); + } else { + NativeClientAccess.execute(new TdApi.SetLogStream(new LogStreamFile(path, maxSize, false))); + } + } catch (Throwable ex) { + ex.printStackTrace(); + return false; + } + return true; + } /** * Sets file path for writing TDLib internal log. By default TDLib writes logs to the System.err. Use this method to @@ -29,8 +52,9 @@ public final class Log { * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future. */ @Deprecated - public static synchronized boolean setFilePath(String filePath) { - return NativeLog.setFilePath(filePath); + public static boolean setFilePath(String filePath) { + LOG_FILE_PATH.set(filePath); + return updateLog(); } /** @@ -41,8 +65,9 @@ public final class Log { * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future. */ @Deprecated - public static synchronized void setMaxFileSize(long maxFileSize) { - NativeLog.setMaxFileSize(maxFileSize); + public static void setMaxFileSize(long maxFileSize) { + LOG_MAX_FILE_SIZE.set(maxFileSize); + updateLog(); } /** @@ -57,8 +82,8 @@ public final class Log { * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogVerbosityLevel}, to be removed in the future. */ @Deprecated - public static synchronized void setVerbosityLevel(int verbosityLevel) { - NativeLog.setVerbosityLevel(verbosityLevel); + public static void setVerbosityLevel(int verbosityLevel) { + NativeClientAccess.execute(new SetLogVerbosityLevel(verbosityLevel)); } /** @@ -68,7 +93,7 @@ public final class Log { * @param fatalErrorCallback Callback that will be called when a fatal error happens. Pass null to restore default * callback. */ - public static synchronized void setFatalErrorCallback(Consumer fatalErrorCallback) { + public static void setFatalErrorCallback(Consumer fatalErrorCallback) { NativeLog.setFatalErrorCallback(fatalErrorCallback); } } diff --git a/src/main/java/it/tdlight/common/NativeClientAccess.java b/src/main/java/it/tdlight/common/NativeClientAccess.java new file mode 100644 index 0000000..ce28140 --- /dev/null +++ b/src/main/java/it/tdlight/common/NativeClientAccess.java @@ -0,0 +1,12 @@ +package it.tdlight.common; + +import it.tdlight.jni.TdApi; +import it.tdlight.jni.TdApi.Function; +import it.tdlight.tdnative.NativeClient; + +final class NativeClientAccess extends NativeClient { + + public static TdApi.Object execute(Function function) { + return nativeClientExecute(function); + } +} diff --git a/src/main/java/it/tdlight/tdnative/NativeClient.java b/src/main/java/it/tdlight/tdnative/NativeClient.java index 5342dd1..beffb6c 100644 --- a/src/main/java/it/tdlight/tdnative/NativeClient.java +++ b/src/main/java/it/tdlight/tdnative/NativeClient.java @@ -2,18 +2,17 @@ package it.tdlight.tdnative; import it.tdlight.jni.TdApi; +@SuppressWarnings("rawtypes") public class NativeClient { protected static native int createNativeClient(); - protected static native void nativeClientSend(int nativeClientId, - long eventId, - TdApi.Function function); + protected static native void nativeClientSend(int nativeClientId, long eventId, TdApi.Function function); protected static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events, double timeout); - protected static native TdApi.Object nativeClientExecute(TdApi.Function function); + protected static native TdApi.Object nativeClientExecute(TdApi.Function function); } diff --git a/src/main/java/it/tdlight/tdnative/NativeLog.java b/src/main/java/it/tdlight/tdnative/NativeLog.java index aaba3d8..064681e 100644 --- a/src/main/java/it/tdlight/tdnative/NativeLog.java +++ b/src/main/java/it/tdlight/tdnative/NativeLog.java @@ -2,73 +2,43 @@ package it.tdlight.tdnative; import it.tdlight.jni.TdApi; import java.util.function.Consumer; +import java.util.concurrent.atomic.AtomicReference; /** - * Class used for managing internal TDLib logging. Use TdApi.*Log* methods instead. + * Class used for managing internal TDLib logging. */ public class NativeLog { - private static final Consumer defaultFatalErrorCallbackPtr = System.err::println; - private static Consumer fatalErrorCallback = defaultFatalErrorCallbackPtr; + private static final Consumer defaultFatalErrorCallback = NativeLog::printFatalError; + private static final AtomicReference> fatalErrorCallback + = new AtomicReference<>(defaultFatalErrorCallback); /** - * Sets file path for writing TDLib internal log. By default TDLib writes logs to the System.err. Use this method to - * write the log to a file instead. - * - * @param filePath Path to a file for writing TDLib internal log. Use an empty path to switch back to logging to the - * System.err. - * @return whether opening the log file succeeded. - * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future. - */ - @Deprecated - public static native boolean setFilePath(String filePath); - - /** - * Changes the maximum size of TDLib log file. - * - * @param maxFileSize The maximum size of the file to where the internal TDLib log is written before the file will be - * auto-rotated. Must be positive. Defaults to 10 MB. - * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future. - */ - @Deprecated - public static native void setMaxFileSize(long maxFileSize); - - /** - * Changes TDLib log verbosity. - * - * @param verbosityLevel New value of log verbosity level. Must be non-negative. Value 0 corresponds to fatal errors, - * value 1 corresponds to java.util.logging.Level.SEVERE, value 2 corresponds to - * java.util.logging.Level.WARNING, value 3 corresponds to java.util.logging.Level.INFO, value 4 - * corresponds to java.util.logging.Level.FINE, value 5 corresponds to - * java.util.logging.Level.FINER, value greater than 5 can be used to enable even more logging. - * Default value of the log verbosity level is 5. - * @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogVerbosityLevel}, to be removed in the future. - */ - @Deprecated - public static native void setVerbosityLevel(int verbosityLevel); - - /** - * This function is called from the JNI when a fatal error happens to provide a better error message. The function - * does not return. + * This function is called from the JNI when a fatal error happens to provide a better error message. + * The function does not return. * * @param errorMessage Error message. */ - private static synchronized void onFatalError(String errorMessage) { - new Thread(() -> NativeLog.fatalErrorCallback.accept(errorMessage)).start(); + private static void onFatalError(String errorMessage) { + new Thread(() -> NativeLog.fatalErrorCallback.get().accept(errorMessage)).start(); } /** - * Sets the callback that will be called when a fatal error happens. None of the TDLib methods can be called from the - * callback. The TDLib will crash as soon as callback returns. By default the callback set to print in stderr. - * - * @param fatalErrorCallback Callback that will be called when a fatal error happens. Pass null to restore default - * callback. + * Sets the callback that will be called when a fatal error happens. + * None of the TDLib methods can be called from the callback. + * TDLib will crash as soon as the callback returns. + * By default the callback set to print in stderr. + * @param fatalErrorCallback Callback that will be called when a fatal error happens. + * Pass null to restore default callback. */ - public static synchronized void setFatalErrorCallback(Consumer fatalErrorCallback) { + public static void setFatalErrorCallback(Consumer fatalErrorCallback) { if (fatalErrorCallback == null) { - NativeLog.fatalErrorCallback = defaultFatalErrorCallbackPtr; - } else { - NativeLog.fatalErrorCallback = fatalErrorCallback; + fatalErrorCallback = defaultFatalErrorCallback; } + NativeLog.fatalErrorCallback.set(fatalErrorCallback); + } + + private static void printFatalError(String errorMessage) { + System.err.println("TDLib fatal error: " + errorMessage); } }