Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28bc7eed authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reduce overhead of writing logcat from protolog method

String.format contains more loop, creates more temporary object
with more conditions than TextUtils.formatSimple.

And the basic syntax provided by formatSimple is enough for use
so far, it would be better to reduce the general cost while
enabling logcat output of protolog.

Bug: 259683790
Test: atest ProtoLogImplTest ProtoLogIntegrationTest LogParserTest
Change-Id: Icbf55c9e75c2343a961a57f83823a90e1f057075
parent bdc9177e
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.internal.protolog.ProtoLogMessage.STR_PARAMS;
import android.annotation.Nullable;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

@@ -44,7 +45,6 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.IllegalFormatConversionException;
import java.util.TreeMap;
import java.util.stream.Collectors;

@@ -108,11 +108,15 @@ public class BaseProtoLogImpl {
            messageString = mViewerConfig.getViewerString(messageHash);
        }
        if (messageString != null) {
            if (args != null) {
                try {
                message = String.format(messageString, args);
            } catch (IllegalFormatConversionException ex) {
                    message = TextUtils.formatSimple(messageString, args);
                } catch (Exception ex) {
                    Slog.w(TAG, "Invalid ProtoLog format string.", ex);
                }
            } else {
                message = messageString;
            }
        }
        if (message == null) {
            StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
+0 −3
Original line number Diff line number Diff line
@@ -74,13 +74,10 @@ public class LogDataType {
                        types.add(LogDataType.BOOLEAN);
                        break;
                    case 'd':
                    case 'o':
                    case 'x':
                        types.add(LogDataType.LONG);
                        break;
                    case 'f':
                    case 'e':
                    case 'g':
                        types.add(LogDataType.DOUBLE);
                        break;
                    case 's':
+4 −3
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@ package com.android.internal.protolog.common;
 * a messageString, which is a format string for the log message (has to be a string literal or
 * a concatenation of string literals) and a vararg array of parameters for the formatter.
 *
 * The syntax for the message string is a subset of {@code java.util.Formatter} syntax.
 * The syntax for the message string depends on
 * {@link android.text.TextUtils#formatSimple(String, Object...)}}.
 * Supported conversions:
 * %b - boolean
 * %d, %o and %x - integral type (Short, Integer or Long)
 * %f, %e and %g - floating point type (Float or Double)
 * %d %x - integral type (Short, Integer or Long)
 * %f - floating point type (Float or Double)
 * %s - string
 * %% - a literal percent character
 * The width and precision modifiers are supported, argument_index and flags are not.
+5 −5
Original line number Diff line number Diff line
@@ -50,17 +50,17 @@ public class ProtoLogIntegrationTest {
        ProtoLogImpl mockedProtoLog = mock(ProtoLogImpl.class);
        runWith(mockedProtoLog, this::testProtoLog);
        verify(mockedProtoLog).log(eq(ProtoLogImpl.LogLevel.ERROR), eq(ProtoLogGroup.TEST_GROUP),
                anyInt(), eq(0b0010101001010111),
                anyInt(), eq(0b0010010111),
                eq(com.android.internal.protolog.ProtoLogGroup.TEST_GROUP.isLogToLogcat()
                        ? "Test completed successfully: %b %d %o %x %e %g %f %% %s"
                        ? "Test completed successfully: %b %d %x %f %% %s"
                        : null),
                eq(new Object[]{true, 1L, 2L, 3L, 0.4, 0.5, 0.6, "ok"}));
                eq(new Object[]{true, 1L, 2L, 0.3, "ok"}));
    }

    private void testProtoLog() {
        ProtoLog.e(ProtoLogGroup.TEST_GROUP,
                "Test completed successfully: %b %d %o %x %e %g %f %% %s.",
                true, 1, 2, 3, 0.4, 0.5, 0.6, "ok");
                "Test completed successfully: %b %d %x %f %% %s",
                true, 1, 2, 0.3, "ok");
    }

    /**
+4 −4
Original line number Diff line number Diff line
@@ -201,24 +201,24 @@ public class ProtoLogImplTest {

    @Test
    public void log_logcatEnabledExternalMessage() {
        when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %o %x %e %g %s %f");
        when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% 0x%x %s %f");
        ProtoLogImpl implSpy = Mockito.spy(mProtoLog);
        TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
        TestProtoLogGroup.TEST_GROUP.setLogToProto(false);

        implSpy.log(
                ProtoLogImpl.LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
                new Object[]{true, 10000, 20000, 30000, 0.0001, 0.00002, "test", 0.000003});
                new Object[]{true, 10000, 30000, "test", 0.000003});

        verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
                ProtoLogImpl.LogLevel.INFO),
                eq("test true 10000 % 47040 7530 1.000000e-04 2.00000e-05 test 0.000003"));
                eq("test true 10000 % 0x7530 test 3.0E-6"));
        verify(mReader).getViewerString(eq(1234));
    }

    @Test
    public void log_logcatEnabledInvalidMessage() {
        when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %o %x %e %g %s %f");
        when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %x %s %f");
        ProtoLogImpl implSpy = Mockito.spy(mProtoLog);
        TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
        TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
Loading