diff --git a/app/src/main/java/com/termux/app/utils/PluginUtils.java b/app/src/main/java/com/termux/app/utils/PluginUtils.java index 3fbd40ebd7..17fbbdb728 100644 --- a/app/src/main/java/com/termux/app/utils/PluginUtils.java +++ b/app/src/main/java/com/termux/app/utils/PluginUtils.java @@ -65,9 +65,12 @@ public static void processPluginExecutionCommandResult(final Context context, St } boolean isPluginExecutionCommandWithPendingResult = executionCommand.isPluginExecutionCommandWithPendingResult(); + boolean isExecutionCommandLoggingEnabled = Logger.shouldEnableLoggingForCustomLogLevel(executionCommand.backgroundCustomLogLevel); // Log the output. ResultData should not be logged if pending result since ResultSender will do it - Logger.logDebugExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, !isPluginExecutionCommandWithPendingResult)); + // or if logging is disabled + Logger.logDebugExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, + !isPluginExecutionCommandWithPendingResult, isExecutionCommandLoggingEnabled)); // If execution command was started by a plugin which expects the result back if (isPluginExecutionCommandWithPendingResult) { @@ -78,11 +81,12 @@ public static void processPluginExecutionCommandResult(final Context context, St setPluginResultDirectoryVariables(executionCommand); // Send result to caller - error = ResultSender.sendCommandResultData(context, logTag, executionCommand.getCommandIdAndLabelLogString(), executionCommand.resultConfig, executionCommand.resultData); + error = ResultSender.sendCommandResultData(context, logTag, executionCommand.getCommandIdAndLabelLogString(), + executionCommand.resultConfig, executionCommand.resultData, isExecutionCommandLoggingEnabled); if (error != null) { // error will be added to existing Errors resultData.setStateFailed(error); - Logger.logDebugExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, true)); + Logger.logDebugExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, true, isExecutionCommandLoggingEnabled)); // Flash and send notification for the error Logger.showToast(context, ResultData.getErrorsListMinimalString(resultData), true); @@ -133,9 +137,11 @@ public static void processPluginExecutionCommandError(final Context context, Str } boolean isPluginExecutionCommandWithPendingResult = executionCommand.isPluginExecutionCommandWithPendingResult(); + boolean isExecutionCommandLoggingEnabled = Logger.shouldEnableLoggingForCustomLogLevel(executionCommand.backgroundCustomLogLevel); // Log the error and any exception. ResultData should not be logged if pending result since ResultSender will do it - Logger.logErrorExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, !isPluginExecutionCommandWithPendingResult)); + Logger.logErrorExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, + !isPluginExecutionCommandWithPendingResult, isExecutionCommandLoggingEnabled)); // If execution command was started by a plugin which expects the result back if (isPluginExecutionCommandWithPendingResult) { @@ -146,11 +152,12 @@ public static void processPluginExecutionCommandError(final Context context, Str setPluginResultDirectoryVariables(executionCommand); // Send result to caller - error = ResultSender.sendCommandResultData(context, logTag, executionCommand.getCommandIdAndLabelLogString(), executionCommand.resultConfig, executionCommand.resultData); + error = ResultSender.sendCommandResultData(context, logTag, executionCommand.getCommandIdAndLabelLogString(), + executionCommand.resultConfig, executionCommand.resultData, isExecutionCommandLoggingEnabled); if (error != null) { // error will be added to existing Errors resultData.setStateFailed(error); - Logger.logErrorExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, true)); + Logger.logErrorExtended(logTag, ExecutionCommand.getExecutionOutputLogString(executionCommand, true, true, isExecutionCommandLoggingEnabled)); forceNotification = true; } @@ -171,7 +178,7 @@ public static void processPluginExecutionCommandError(final Context context, Str } - /** Set variables which will be used by {@link ResultSender#sendCommandResultData(Context, String, String, ResultConfig, ResultData)} + /** Set variables which will be used by {@link ResultSender#sendCommandResultData(Context, String, String, ResultConfig, ResultData, boolean)} * to send back the result via {@link ResultConfig#resultPendingIntent}. */ public static void setPluginResultPendingIntentVariables(ExecutionCommand executionCommand) { ResultConfig resultConfig = executionCommand.resultConfig; @@ -186,7 +193,7 @@ public static void setPluginResultPendingIntentVariables(ExecutionCommand execut resultConfig.resultErrmsgKey = TERMUX_SERVICE.EXTRA_PLUGIN_RESULT_BUNDLE_ERRMSG; } - /** Set variables which will be used by {@link ResultSender#sendCommandResultData(Context, String, String, ResultConfig, ResultData)} + /** Set variables which will be used by {@link ResultSender#sendCommandResultData(Context, String, String, ResultConfig, ResultData, boolean)} * to send back the result by writing it to files in {@link ResultConfig#resultDirectoryPath}. */ public static void setPluginResultDirectoryVariables(ExecutionCommand executionCommand) { ResultConfig resultConfig = executionCommand.resultConfig; diff --git a/termux-shared/src/main/java/com/termux/shared/logger/Logger.java b/termux-shared/src/main/java/com/termux/shared/logger/Logger.java index fe41838712..176ba56fc6 100644 --- a/termux-shared/src/main/java/com/termux/shared/logger/Logger.java +++ b/termux-shared/src/main/java/com/termux/shared/logger/Logger.java @@ -436,4 +436,11 @@ public static boolean isLogLevelValid(Integer logLevel) { return (logLevel != null && logLevel >= LOG_LEVEL_OFF && logLevel <= MAX_LOG_LEVEL); } + /** Check if custom log level is valid and >= {@link #CURRENT_LOG_LEVEL}. If custom log level is + * not valid then {@link #LOG_LEVEL_VERBOSE} must be >= {@link #CURRENT_LOG_LEVEL}. */ + public static boolean shouldEnableLoggingForCustomLogLevel(Integer customLogLevel) { + customLogLevel = Logger.isLogLevelValid(customLogLevel) ? customLogLevel: Logger.LOG_LEVEL_VERBOSE; + return (customLogLevel >= CURRENT_LOG_LEVEL); + } + } diff --git a/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java b/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java index 84ac21db32..b908e1d07f 100644 --- a/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java +++ b/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java @@ -85,8 +85,10 @@ public int getValue() { /** * The {@link ExecutionCommand} custom log level for background {@link com.termux.shared.shell.TermuxTask} - * commands. By default, @link com.termux.shared.shell.StreamGobbler} only logs if {@link Logger} - * `CURRENT_LOG_LEVEL` is >= {@link Logger#LOG_LEVEL_VERBOSE}. + * commands. By default, @link com.termux.shared.shell.StreamGobbler} only logs stdout and + * stderr if {@link Logger} `CURRENT_LOG_LEVEL` is >= {@link Logger#LOG_LEVEL_VERBOSE} and + * {@link com.termux.shared.shell.TermuxTask} only logs stdin if `CURRENT_LOG_LEVEL` is >= + * {@link Logger#LOG_LEVEL_DEBUG}. */ public Integer backgroundCustomLogLevel; @@ -242,7 +244,7 @@ public String toString() { if (!hasExecuted()) return getExecutionInputLogString(this, true, true); else { - return getExecutionOutputLogString(this, true, true); + return getExecutionOutputLogString(this, true, true, true); } } @@ -298,9 +300,10 @@ public static String getExecutionInputLogString(final ExecutionCommand execution * @param executionCommand The {@link ExecutionCommand} to convert. * @param ignoreNull Set to {@code true} if non-critical {@code null} values are to be ignored. * @param logResultData Set to {@code true} if {@link #resultData} should be logged. + * @param logStdoutAndStderr Set to {@code true} if {@link ResultData#stdout} and {@link ResultData#stderr} should be logged. * @return Returns the log friendly {@link String}. */ - public static String getExecutionOutputLogString(final ExecutionCommand executionCommand, boolean ignoreNull, boolean logResultData) { + public static String getExecutionOutputLogString(final ExecutionCommand executionCommand, boolean ignoreNull, boolean logResultData, boolean logStdoutAndStderr) { if (executionCommand == null) return "null"; StringBuilder logString = new StringBuilder(); @@ -311,7 +314,7 @@ public static String getExecutionOutputLogString(final ExecutionCommand executio logString.append("\n").append(executionCommand.getCurrentStateLogString()); if (logResultData) - logString.append("\n").append(ResultData.getResultDataLogString(executionCommand.resultData, ignoreNull)); + logString.append("\n").append(ResultData.getResultDataLogString(executionCommand.resultData, logStdoutAndStderr)); return logString.toString(); } @@ -328,7 +331,7 @@ public static String getDetailedLogString(final ExecutionCommand executionComman StringBuilder logString = new StringBuilder(); logString.append(getExecutionInputLogString(executionCommand, false, true)); - logString.append(getExecutionOutputLogString(executionCommand, false, true)); + logString.append(getExecutionOutputLogString(executionCommand, false, true, true)); logString.append("\n").append(executionCommand.getCommandDescriptionLogString()); logString.append("\n").append(executionCommand.getCommandHelpLogString()); diff --git a/termux-shared/src/main/java/com/termux/shared/models/ResultData.java b/termux-shared/src/main/java/com/termux/shared/models/ResultData.java index 85e1b06b07..2501653edb 100644 --- a/termux-shared/src/main/java/com/termux/shared/models/ResultData.java +++ b/termux-shared/src/main/java/com/termux/shared/models/ResultData.java @@ -133,16 +133,18 @@ public String toString() { * Get a log friendly {@link String} for {@link ResultData} parameters. * * @param resultData The {@link ResultData} to convert. - * @param ignoreNull Set to {@code true} if non-critical {@code null} values are to be ignored. + * @param logStdoutAndStderr Set to {@code true} if {@link #stdout} and {@link #stderr} should be logged. * @return Returns the log friendly {@link String}. */ - public static String getResultDataLogString(final ResultData resultData, boolean ignoreNull) { + public static String getResultDataLogString(final ResultData resultData, boolean logStdoutAndStderr) { if (resultData == null) return "null"; StringBuilder logString = new StringBuilder(); - logString.append("\n").append(resultData.getStdoutLogString()); - logString.append("\n").append(resultData.getStderrLogString()); + if (logStdoutAndStderr) { + logString.append("\n").append(resultData.getStdoutLogString()); + logString.append("\n").append(resultData.getStderrLogString()); + } logString.append("\n").append(resultData.getExitCodeLogString()); logString.append("\n\n").append(getErrorsListLogString(resultData)); diff --git a/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java b/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java index bac25bd683..20b384e333 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java @@ -34,22 +34,24 @@ public class ResultSender { * @param label The label for the command. * @param resultConfig The {@link ResultConfig} object containing information on how to send the result. * @param resultData The {@link ResultData} object containing result data. + * @param logStdoutAndStderr Set to {@code true} if {@link ResultData#stdout} and {@link ResultData#stderr} + * should be logged. * @return Returns the {@link Error} if failed to send the result, otherwise {@code null}. */ - public static Error sendCommandResultData(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData) { + public static Error sendCommandResultData(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData, boolean logStdoutAndStderr) { if (context == null || resultConfig == null || resultData == null) return FunctionErrno.ERRNO_NULL_OR_EMPTY_PARAMETERS.getError("context, resultConfig or resultData", "sendCommandResultData"); Error error; if (resultConfig.resultPendingIntent != null) { - error = sendCommandResultDataWithPendingIntent(context, logTag, label, resultConfig, resultData); + error = sendCommandResultDataWithPendingIntent(context, logTag, label, resultConfig, resultData, logStdoutAndStderr); if (error != null || resultConfig.resultDirectoryPath == null) return error; } if (resultConfig.resultDirectoryPath != null) { - return sendCommandResultDataToDirectory(context, logTag, label, resultConfig, resultData); + return sendCommandResultDataToDirectory(context, logTag, label, resultConfig, resultData, logStdoutAndStderr); } else { return FunctionErrno.ERRNO_UNSET_PARAMETERS.getError("resultConfig.resultPendingIntent or resultConfig.resultDirectoryPath", "sendCommandResultData"); } @@ -63,15 +65,17 @@ public static Error sendCommandResultData(Context context, String logTag, String * @param label The label for the command. * @param resultConfig The {@link ResultConfig} object containing information on how to send the result. * @param resultData The {@link ResultData} object containing result data. + * @param logStdoutAndStderr Set to {@code true} if {@link ResultData#stdout} and {@link ResultData#stderr} + * should be logged. * @return Returns the {@link Error} if failed to send the result, otherwise {@code null}. */ - public static Error sendCommandResultDataWithPendingIntent(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData) { + public static Error sendCommandResultDataWithPendingIntent(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData, boolean logStdoutAndStderr) { if (context == null || resultConfig == null || resultData == null || resultConfig.resultPendingIntent == null || resultConfig.resultBundleKey == null) return FunctionErrno.ERRNO_NULL_OR_EMPTY_PARAMETER.getError("context, resultConfig, resultData, resultConfig.resultPendingIntent or resultConfig.resultBundleKey", "sendCommandResultDataWithPendingIntent"); logTag = DataUtils.getDefaultIfNull(logTag, LOG_TAG); - Logger.logDebugExtended(logTag, "Sending result for command \"" + label + "\":\n" + resultConfig.toString() + "\n" + resultData.toString()); + Logger.logDebugExtended(logTag, "Sending result for command \"" + label + "\":\n" + resultConfig.toString() + "\n" + ResultData.getResultDataLogString(resultData, logStdoutAndStderr)); String resultDataStdout = resultData.stdout.toString(); String resultDataStderr = resultData.stderr.toString(); @@ -152,9 +156,11 @@ public static Error sendCommandResultDataWithPendingIntent(Context context, Stri * @param label The label for the command. * @param resultConfig The {@link ResultConfig} object containing information on how to send the result. * @param resultData The {@link ResultData} object containing result data. + * @param logStdoutAndStderr Set to {@code true} if {@link ResultData#stdout} and {@link ResultData#stderr} + * should be logged. * @return Returns the {@link Error} if failed to send the result, otherwise {@code null}. */ - public static Error sendCommandResultDataToDirectory(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData) { + public static Error sendCommandResultDataToDirectory(Context context, String logTag, String label, ResultConfig resultConfig, ResultData resultData, boolean logStdoutAndStderr) { if (context == null || resultConfig == null || resultData == null || DataUtils.isNullOrEmpty(resultConfig.resultDirectoryPath)) return FunctionErrno.ERRNO_NULL_OR_EMPTY_PARAMETER.getError("context, resultConfig, resultData or resultConfig.resultDirectoryPath", "sendCommandResultDataToDirectory"); @@ -177,7 +183,7 @@ public static Error sendCommandResultDataToDirectory(Context context, String log resultConfig.resultDirectoryPath = FileUtils.getCanonicalPath(resultConfig.resultDirectoryPath, null); - Logger.logDebugExtended(logTag, "Writing result for command \"" + label + "\":\n" + resultConfig.toString() + "\n" + resultData.toString()); + Logger.logDebugExtended(logTag, "Writing result for command \"" + label + "\":\n" + resultConfig.toString() + "\n" + ResultData.getResultDataLogString(resultData, logStdoutAndStderr)); // If resultDirectoryPath is not a directory, or is not readable or writable, then just return // Creation of missing directory and setting of read, write and execute permissions are diff --git a/termux-shared/src/main/java/com/termux/shared/shell/StreamGobbler.java b/termux-shared/src/main/java/com/termux/shared/shell/StreamGobbler.java index e17ecefb23..aae4186549 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/StreamGobbler.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/StreamGobbler.java @@ -88,7 +88,7 @@ public interface OnStreamClosedListener { @Nullable private final OnStreamClosedListener streamClosedListener; @Nullable - private final Integer mLlogLevel; + private final Integer mLogLevel; private volatile boolean active = true; private volatile boolean calledOnClose = false; @@ -104,7 +104,7 @@ public interface OnStreamClosedListener { * @param shell Name of the shell * @param inputStream InputStream to read from * @param outputList {@literal List} to write to, or null - * @param logLevel The custom log level to use for logging by command output. If set to + * @param logLevel The custom log level to use for logging the command output. If set to * {@code null}, then {@link Logger#LOG_LEVEL_VERBOSE} will be used. */ @AnyThread @@ -121,7 +121,7 @@ public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, stringWriter = null; lineListener = null; - mLlogLevel = logLevel; + mLogLevel = logLevel; } /** @@ -136,7 +136,7 @@ public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, * @param shell Name of the shell * @param inputStream InputStream to read from * @param outputString {@literal List} to write to, or null - * @param logLevel The custom log level to use for logging by command output. If set to + * @param logLevel The custom log level to use for logging the command output. If set to * {@code null}, then {@link Logger#LOG_LEVEL_VERBOSE} will be used. */ @AnyThread @@ -153,7 +153,7 @@ public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, stringWriter = outputString; lineListener = null; - mLlogLevel = logLevel; + mLogLevel = logLevel; } /** @@ -167,7 +167,7 @@ public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, * @param inputStream InputStream to read from * @param onLineListener OnLineListener callback * @param onStreamClosedListener OnStreamClosedListener callback - * @param logLevel The custom log level to use for logging by command output. If set to + * @param logLevel The custom log level to use for logging the command output. If set to * {@code null}, then {@link Logger#LOG_LEVEL_VERBOSE} will be used. */ @AnyThread @@ -185,28 +185,22 @@ public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, stringWriter = null; lineListener = onLineListener; - mLlogLevel = logLevel; + mLogLevel = logLevel; } @Override public void run() { String defaultLogTag = Logger.DEFAULT_LOG_TAG; - int currentLogLevel = Logger.getLogLevel(); - - int customLogLevel; - if (Logger.isLogLevelValid(mLlogLevel)) { - customLogLevel = mLlogLevel; - Logger.logVerbose(LOG_TAG, "Using custom log level: " + customLogLevel + ", current log level: " + currentLogLevel); - } else { - customLogLevel = Logger.LOG_LEVEL_VERBOSE; - } + boolean loggingEnabled = Logger.shouldEnableLoggingForCustomLogLevel(mLogLevel); + if (loggingEnabled) + Logger.logVerbose(LOG_TAG, "Using custom log level: " + mLogLevel + ", current log level: " + Logger.getLogLevel()); // keep reading the InputStream until it ends (or an error occurs) // optionally pausing when a command is executed that consumes the InputStream itself try { String line; while ((line = reader.readLine()) != null) { - if (customLogLevel >= currentLogLevel) + if (loggingEnabled) Logger.logVerboseForce(defaultLogTag + "Command", String.format(Locale.ENGLISH, "[%s] %s", shell, line)); // This will get truncated by LOGGER_ENTRY_MAX_LEN, likely 4KB if (stringWriter != null) stringWriter.append(line).append("\n"); diff --git a/termux-shared/src/main/java/com/termux/shared/shell/TermuxTask.java b/termux-shared/src/main/java/com/termux/shared/shell/TermuxTask.java index 8f8974ac5d..da27e99666 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/TermuxTask.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/TermuxTask.java @@ -82,8 +82,8 @@ public static TermuxTask execute(@NonNull final Context context, @NonNull Execut } // No need to log stdin if logging is disabled, like for app internal scripts - int customLogLevel = Logger.isLogLevelValid(executionCommand.backgroundCustomLogLevel) ? executionCommand.backgroundCustomLogLevel: Logger.LOG_LEVEL_VERBOSE; - Logger.logDebugExtended(LOG_TAG, ExecutionCommand.getExecutionInputLogString(executionCommand, true, customLogLevel >= Logger.getLogLevel())); + Logger.logDebugExtended(LOG_TAG, ExecutionCommand.getExecutionInputLogString(executionCommand, + true, Logger.shouldEnableLoggingForCustomLogLevel(executionCommand.backgroundCustomLogLevel))); String taskName = ShellUtils.getExecutableBasename(executionCommand.executable);