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

Commit 42dfdf00 authored by Adam Pardyl's avatar Adam Pardyl Committed by Android (Google) Code Review
Browse files

Merge "Implement the ProtoLogTool"

parents 8f0ecddf fab9ad6a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -28,3 +28,13 @@ cc_library_static {
        "android/bluetooth/smp/enums.proto",
    ],
}

java_library_host {
    name: "windowmanager-log-proto",
    srcs: [
        "android/server/windowmanagerlog.proto"
    ],
    proto: {
        type: "full",
    },
}
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

package com.android.server.wm;

option java_multiple_files = true;

/* represents a single log entry */
message ProtoLogMessage {
    /* log statement identifier, created from message string and log level. */
    optional fixed32 message_hash = 1;
    /* log time, relative to the elapsed system time clock. */
    optional fixed64 elapsed_realtime_nanos = 2;
    /* string parameters passed to the log call. */
    repeated string str_params = 3;
    /* integer parameters passed to the log call. */
    repeated sint64 sint64_params = 4 [packed=true];
    /* floating point parameters passed to the log call. */
    repeated double double_params = 5 [packed=true];
    /* boolean parameters passed to the log call. */
    repeated bool boolean_params = 6 [packed=true];
}

/* represents a log file containing window manager log entries.
   Encoded, it should start with 0x9 0x57 0x49 0x4e 0x44 0x4f 0x4c 0x4f 0x47 (.WINDOLOG), such
   that they can be easily identified. */
message WindowManagerLogFileProto {
    /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
       (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
        constants into .proto files. */
    enum MagicNumber {
        INVALID = 0;
        MAGIC_NUMBER_L = 0x444e4957; /* WIND (little-endian ASCII) */
        MAGIC_NUMBER_H = 0x474f4c4f; /* OLOG (little-endian ASCII) */
    }

    /* the magic number header */
    optional fixed64 magic_number = 1;
    /* log proto version. */
    optional string version = 2;
    /* offset between real-time clock and elapsed system time clock in miliseconds.
       Calculated as: (System.currentTimeMillis() - (SystemClock.elapsedRealtimeNanos() / 1000000) */
    optional fixed64 realTimeToElapsedTimeOffsetMillis = 3;
    /* log entries */
    repeated ProtoLogMessage log = 4;
}
+28 −0
Original line number Diff line number Diff line
java_binary_host {
    name: "protologtool",
    manifest: "manifest.txt",
    srcs: [
        "src/**/*.kt",
    ],
    static_libs: [
        "javaparser",
        "windowmanager-log-proto",
        "jsonlib",
    ],
}

java_test_host {
    name: "protologtool-tests",
    test_suites: ["general-tests"],
    srcs: [
        "src/**/*.kt",
        "tests/**/*.kt",
    ],
    static_libs: [
        "javaparser",
        "windowmanager-log-proto",
        "jsonlib",
        "junit",
        "mockito",
    ],
}
+106 −0
Original line number Diff line number Diff line
# ProtoLogTool

Code transformation tool and viewer for ProtoLog.

## What does it do?

ProtoLogTool incorporates three different modes of operation:

### Code transformation

Command: `process <protolog class path> <protolog implementation class path>
 <protolog groups class path> <config.jar> [<input.java>] <output.srcjar>`

In this mode ProtoLogTool transforms every ProtoLog logging call in form of:
```java
ProtoLog.x(ProtoLogGroup.GROUP_NAME, "Format string %d %s", value1, value2);
```
into:
```java
if (GROUP_NAME.isLogToAny()) {
    ProtoLogImpl.x(ProtoLogGroup.GROUP_NAME, 123456, "Format string %d %s or null", value1, value2);
}
```
where `ProtoLog`, `ProtoLogImpl` and `ProtoLogGroup` are the classes provided as arguments
 (can be imported, static imported or full path, wildcard imports are not allowed) and, `x` is the
 logging method. The transformation is done on the source level. A hash is generated from the format
 string and log level and inserted after the `ProtoLogGroup` argument. The format string is replaced
 by `null` if `ProtoLogGroup.GROUP_NAME.isLogToLogcat()` returns false. If `ProtoLogGroup.GROUP_NAME.isEnabled()`
 returns false the log statement is removed entirely from the resultant code.

Input is provided as a list of java source file names. Transformed source is saved to a single
source jar file. The ProtoLogGroup class with all dependencies should be provided as a compiled
jar file (config.jar).

### Viewer config generation

Command: `viewerconf <protolog class path> <protolog implementation class path
<protolog groups class path> <config.jar> [<input.java>] <output.json>`

This command is similar in it's syntax to the previous one, only instead of creating a processed source jar
it writes a viewer configuration file with following schema:
```json
{
  "version": "1.0.0",
  "messages": {
    "123456": {
      "message": "Format string %d %s",
      "level": "ERROR",
      "group": "GROUP_NAME"
    },
  },
  "groups": {
    "GROUP_NAME": {
      "tag": "TestLog"
    }
  }
}

```

### Binary log viewing

Command: `read <viewer.json> <wm_log.pb>`

Reads the binary ProtoLog log file and outputs a human-readable LogCat-like text log.

## What is ProtoLog?

ProtoLog is a logging system created for the WindowManager project. It allows both binary and text logging
and is tunable in runtime. It consists of 3 different submodules:
* logging system built-in the Android app,
* log viewer for reading binary logs,
* a code processing tool.

ProtoLog is designed to reduce both application size (and by that memory usage) and amount of resources needed
for logging. This is achieved by replacing log message strings with their hashes and only loading to memory/writing
full log messages when necessary.

### Text logging

For text-based logs Android LogCat is used as a backend. Message strings are loaded from a viewer config
located on the device when needed.

### Binary logging

Binary logs are saved as Protocol Buffers file. They can be read using the ProtoLog tool or specialised
viewer like Winscope.

## How to use ProtoLog?

### Adding a new logging group or log statement

To add a new ProtoLogGroup simple create a new enum ProtoLogGroup member with desired parameters.

To add a new logging statement just add a new call to ProtoLog.x where x is a log level.

After doing any changes to logging groups or statements you should run `make update-protolog` to update
viewer configuration saved in the code repository.

## How to change settings on device in runtime?
Use the `adb shell su root cmd window logging` command. To get help just type
`adb shell su root cmd window logging help`.



+7 −0
Original line number Diff line number Diff line
{
  "presubmit": [
    {
      "name": "protologtool-tests"
    }
  ]
}
Loading