Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / scripts / tools / esp32_log_cat.py
1 #!/usr/bin/env python
2
3 #
4 #    Copyright (c) 2021 Project CHIP Authors
5 #
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
9 #
10 #        http://www.apache.org/licenses/LICENSE-2.0
11 #
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.
17 #
18
19 #
20 # Required modules:
21 #    pyserial
22 #    coloredlogs
23 #
24 # Example usage to show only warning and above messages:
25 #
26 #   ./scripts/esp32_log_cat.py --log-level WARNING
27 #
28
29 import argparse
30 import coloredlogs
31 import logging
32 import serial
33
34
35 class LogPrinter:
36     """Converts raw bytes from a serial output to python log outputs."""
37
38     def __init__(self, logger):
39         # a severity state is kept to account for multiline messages
40         self.severity = 'I'
41         self.logger = logger
42
43     def ExtractSeverity(self, log_line: str):
44         if len(log_line) < 2:
45             return
46
47         # Log line expected to start like 'E ', 'I ', ...
48         if log_line[1] != ' ':
49             return
50
51         if log_line[0] in 'EWIV':
52             self.severity = log_line[0]
53
54
55     def Log(self, raw):
56         """Converts raw bytes from serial output into python logging.
57
58         Strips out any color encoding from the line and uses the prefix to decide
59         log type.
60         """
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'
64
65         if raw.startswith(b'\x1b['):
66             raw = raw[raw.find(b'm')+1:]
67         raw = raw.decode('utf8').strip()
68
69         self.ExtractSeverity(raw)
70
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)
79
80
81 def main():
82   """Main task if executed standalone."""
83   parser = argparse.ArgumentParser(description='Output nicely colored logs from esp32')
84
85   parser.add_argument(
86       '--device',
87       default='/dev/ttyUSB0',
88       type=str,
89       help='What serial device to open.')
90
91   parser.add_argument(
92       '--baudrate',
93       default=115200,
94       type=int,
95       help='Baudrate for the serial device.')
96
97   parser.add_argument(
98       '--log-level',
99       default=logging.DEBUG,
100       type=lambda x: getattr(logging, x),
101       help='Log filtering to apply.')
102
103   args = parser.parse_args()
104
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')
108
109   logger = logging.getLogger(args.device)
110   logger.setLevel(args.log_level)
111
112   printer = LogPrinter(logger)
113   ser = serial.Serial(args.device, args.baudrate)
114   while True:
115       data = ser.readline()
116       printer.Log(data)
117
118
119 if __name__ == '__main__':
120   # execute only if run as a script
121   main()