| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- #!/usr/bin/env python
- #
- # Copyright (c) 2021 Project CHIP Authors
- #
- # 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.
- #
- #
- # Required modules:
- # pyserial
- # coloredlogs
- #
- # Example usage to show only warning and above messages:
- #
- # ./scripts/esp32_log_cat.py --log-level WARNING
- #
- import argparse
- import logging
- import coloredlogs
- import serial
- class LogPrinter:
- """Converts raw bytes from a serial output to python log outputs."""
- def __init__(self, logger):
- # a severity state is kept to account for multiline messages
- self.severity = 'I'
- self.logger = logger
- def ExtractSeverity(self, log_line: str):
- if len(log_line) < 2:
- return
- # Log line expected to start like 'E ', 'I ', ...
- if log_line[1] != ' ':
- return
- if log_line[0] in 'EWIV':
- self.severity = log_line[0]
- def Log(self, raw):
- """Converts raw bytes from serial output into python logging.
- Strips out any color encoding from the line and uses the prefix to decide
- log type.
- """
- # ESP32 serial lines already contain color encoding information and look like:
- # b'\x1b[0;32mI (4921) app-devicecallbacks: Current free heap: 125656\r\n'
- # b'\x1b[0;31mE (1491) chip[DL]: Long dispatch time: 635 ms\x1b[0m'
- if raw.startswith(b'\x1b['):
- raw = raw[raw.find(b'm')+1:]
- raw = raw.decode('utf8').strip()
- self.ExtractSeverity(raw)
- if self.severity == 'E':
- self.logger.error('%s', raw)
- elif self.severity == 'W':
- self.logger.warning('%s', raw)
- elif self.severity == 'I':
- self.logger.info('%s', raw)
- elif self.severity == 'V':
- self.logger.debug('%s', raw)
- def main():
- """Main task if executed standalone."""
- parser = argparse.ArgumentParser(
- description='Output nicely colored logs from esp32')
- parser.add_argument(
- '--device',
- default='/dev/ttyUSB0',
- type=str,
- help='What serial device to open.')
- parser.add_argument(
- '--baudrate',
- default=115200,
- type=int,
- help='Baudrate for the serial device.')
- parser.add_argument(
- '--log-level',
- default=logging.DEBUG,
- type=lambda x: getattr(logging, x),
- help='Log filtering to apply.')
- args = parser.parse_args()
- # Ensures somewhat pretty logging of what is going on
- logging.basicConfig(level=args.log_level)
- coloredlogs.install(fmt='%(asctime)s %(name)s %(levelname)-7s %(message)s')
- logger = logging.getLogger(args.device)
- logger.setLevel(args.log_level)
- printer = LogPrinter(logger)
- ser = serial.Serial(args.device, args.baudrate)
- while True:
- data = ser.readline()
- printer.Log(data)
- if __name__ == '__main__':
- # execute only if run as a script
- main()
|