4 # Copyright (c) 2021 Project CHIP Authors
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
24 # Example usage to show only warning and above messages:
26 # ./scripts/esp32_log_cat.py --log-level WARNING
36 """Converts raw bytes from a serial output to python log outputs."""
38 def __init__(self, logger):
39 # a severity state is kept to account for multiline messages
43 def ExtractSeverity(self, log_line: str):
47 # Log line expected to start like 'E ', 'I ', ...
48 if log_line[1] != ' ':
51 if log_line[0] in 'EWIV':
52 self.severity = log_line[0]
56 """Converts raw bytes from serial output into python logging.
58 Strips out any color encoding from the line and uses the prefix to decide
61 # ESP32 serial lines already contain color encoding information and look like:
62 # b'\x1b[0;32mI (4921) app-devicecallbacks: Current free heap: 125656\r\n'
63 # b'\x1b[0;31mE (1491) chip[DL]: Long dispatch time: 635 ms\x1b[0m'
65 if raw.startswith(b'\x1b['):
66 raw = raw[raw.find(b'm')+1:]
67 raw = raw.decode('utf8').strip()
69 self.ExtractSeverity(raw)
71 if self.severity == 'E':
72 self.logger.error('%s', raw)
73 elif self.severity == 'W':
74 self.logger.warning('%s', raw)
75 elif self.severity == 'I':
76 self.logger.info('%s', raw)
77 elif self.severity == 'V':
78 self.logger.debug('%s', raw)
82 """Main task if executed standalone."""
83 parser = argparse.ArgumentParser(description='Output nicely colored logs from esp32')
87 default='/dev/ttyUSB0',
89 help='What serial device to open.')
95 help='Baudrate for the serial device.')
99 default=logging.DEBUG,
100 type=lambda x: getattr(logging, x),
101 help='Log filtering to apply.')
103 args = parser.parse_args()
105 # Ensures somewhat pretty logging of what is going on
106 logging.basicConfig(level=args.log_level);
107 coloredlogs.install(fmt='%(asctime)s %(name)s %(levelname)-7s %(message)s')
109 logger = logging.getLogger(args.device)
110 logger.setLevel(args.log_level)
112 printer = LogPrinter(logger)
113 ser = serial.Serial(args.device, args.baudrate)
115 data = ser.readline()
119 if __name__ == '__main__':
120 # execute only if run as a script