Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 1 | # ProtoLogTool |
| 2 | |
| 3 | Code transformation tool and viewer for ProtoLog. |
| 4 | |
| 5 | ## What does it do? |
| 6 | |
| 7 | ProtoLogTool incorporates three different modes of operation: |
| 8 | |
| 9 | ### Code transformation |
| 10 | |
Pablo Gamito | 329813a | 2024-02-13 14:27:15 +0000 | [diff] [blame] | 11 | Command: `protologtool transform-protolog-calls |
| 12 | --protolog-class <protolog class name> |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 13 | --loggroups-class <protolog groups class name> |
| 14 | --loggroups-jar <config jar path> |
Pablo Gamito | 329813a | 2024-02-13 14:27:15 +0000 | [diff] [blame] | 15 | --viewer-config-file-path <protobuf viewer config file path> |
| 16 | --legacy-viewer-config-file-path <legacy json.gz viewer config file path> |
| 17 | --legacy-output-file-path <.winscope file path to write the legacy trace to> |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 18 | --output-srcjar <output.srcjar> |
| 19 | [<input.java>]` |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 20 | |
| 21 | In this mode ProtoLogTool transforms every ProtoLog logging call in form of: |
| 22 | ```java |
| 23 | ProtoLog.x(ProtoLogGroup.GROUP_NAME, "Format string %d %s", value1, value2); |
| 24 | ``` |
| 25 | into: |
| 26 | ```java |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 27 | if (ProtoLogImpl.isEnabled(GROUP_NAME)) { |
| 28 | int protoLogParam0 = value1; |
| 29 | String protoLogParam1 = String.valueOf(value2); |
| 30 | ProtoLogImpl.x(ProtoLogGroup.GROUP_NAME, 123456, 0b0100, "Format string %d %s or null", protoLogParam0, protoLogParam1); |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 31 | } |
| 32 | ``` |
| 33 | where `ProtoLog`, `ProtoLogImpl` and `ProtoLogGroup` are the classes provided as arguments |
| 34 | (can be imported, static imported or full path, wildcard imports are not allowed) and, `x` is the |
| 35 | logging method. The transformation is done on the source level. A hash is generated from the format |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 36 | string, log level and log group name and inserted after the `ProtoLogGroup` argument. After the hash |
| 37 | we insert a bitmask specifying the types of logged parameters. The format string is replaced |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 38 | by `null` if `ProtoLogGroup.GROUP_NAME.isLogToLogcat()` returns false. If `ProtoLogGroup.GROUP_NAME.isEnabled()` |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 39 | returns false the log statement is removed entirely from the resultant code. The real generated code is inlined |
| 40 | and a number of new line characters is added as to preserve line numbering in file. |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 41 | |
| 42 | Input is provided as a list of java source file names. Transformed source is saved to a single |
| 43 | source jar file. The ProtoLogGroup class with all dependencies should be provided as a compiled |
| 44 | jar file (config.jar). |
| 45 | |
| 46 | ### Viewer config generation |
| 47 | |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 48 | Command: `generate-viewer-config |
Pablo Gamito | 329813a | 2024-02-13 14:27:15 +0000 | [diff] [blame] | 49 | --protolog-class <protolog class name> |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 50 | --loggroups-class <protolog groups class name> |
| 51 | --loggroups-jar <config jar path> |
Pablo Gamito | 329813a | 2024-02-13 14:27:15 +0000 | [diff] [blame] | 52 | --viewer-config-type <proto|json> |
| 53 | --viewer-config <viewer.json> |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 54 | [<input.java>]` |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 55 | |
| 56 | This command is similar in it's syntax to the previous one, only instead of creating a processed source jar |
| 57 | it writes a viewer configuration file with following schema: |
| 58 | ```json |
| 59 | { |
| 60 | "version": "1.0.0", |
| 61 | "messages": { |
| 62 | "123456": { |
| 63 | "message": "Format string %d %s", |
| 64 | "level": "ERROR", |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 65 | "group": "GROUP_NAME", |
| 66 | "at": "com\/android\/server\/example\/Class.java" |
| 67 | } |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 68 | }, |
| 69 | "groups": { |
| 70 | "GROUP_NAME": { |
| 71 | "tag": "TestLog" |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | ``` |
| 77 | |
| 78 | ### Binary log viewing |
| 79 | |
Pablo Gamito | 329813a | 2024-02-13 14:27:15 +0000 | [diff] [blame] | 80 | Command: `read-log --viewer-config <viewer.json> <wm_log.pb>` |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 81 | |
| 82 | Reads the binary ProtoLog log file and outputs a human-readable LogCat-like text log. |
| 83 | |
| 84 | ## What is ProtoLog? |
| 85 | |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 86 | ProtoLog is a generic logging system created for the WindowManager project. It allows both binary and text logging |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 87 | and is tunable in runtime. It consists of 3 different submodules: |
| 88 | * logging system built-in the Android app, |
| 89 | * log viewer for reading binary logs, |
| 90 | * a code processing tool. |
| 91 | |
| 92 | ProtoLog is designed to reduce both application size (and by that memory usage) and amount of resources needed |
| 93 | for logging. This is achieved by replacing log message strings with their hashes and only loading to memory/writing |
| 94 | full log messages when necessary. |
| 95 | |
| 96 | ### Text logging |
| 97 | |
| 98 | For text-based logs Android LogCat is used as a backend. Message strings are loaded from a viewer config |
| 99 | located on the device when needed. |
| 100 | |
| 101 | ### Binary logging |
| 102 | |
| 103 | Binary logs are saved as Protocol Buffers file. They can be read using the ProtoLog tool or specialised |
| 104 | viewer like Winscope. |
| 105 | |
| 106 | ## How to use ProtoLog? |
| 107 | |
| 108 | ### Adding a new logging group or log statement |
| 109 | |
| 110 | To add a new ProtoLogGroup simple create a new enum ProtoLogGroup member with desired parameters. |
| 111 | |
| 112 | To add a new logging statement just add a new call to ProtoLog.x where x is a log level. |
| 113 | |
Adam Pardyl | 9550999 | 2019-09-27 10:09:40 +0200 | [diff] [blame] | 114 | After doing any changes to logging groups or statements you should build the project and follow instructions printed by the tool. |
Adam Pardyl | fab9ad6 | 2019-08-27 02:07:16 +0200 | [diff] [blame] | 115 | |
| 116 | ## How to change settings on device in runtime? |
| 117 | Use the `adb shell su root cmd window logging` command. To get help just type |
| 118 | `adb shell su root cmd window logging help`. |
| 119 | |
| 120 | |
| 121 | |
| 122 | |