xref: /openbmc/bmcweb/scripts/replace_logs.py (revision a529a6aa)
1#!/usr/bin/python3
2import os
3import re
4from subprocess import check_output
5
6"""
7This script is intended to aid in the replacement of bmcweb log lines from
8BMCWEB_LOG_CRITICAL << "foo" << arg;
9to the new fmt style form
10BMCWEB_LOG_CRITICAL("foo{}", arg);
11
12It is intended to be a 99% correct tool, and in some cases, some amount of
13manual intervention is required once the conversion has been done.  Some
14things it doesn't handle:
15
16ptrs need to be wrapped in logPtr().  This script tries to do the common
17cases, but can't handle every one.
18
19types of boost::ip::tcp::endpoint/address needs .to_string() called on it
20in the args section
21
22arguments that were previously build by in-line operator+ construction of
23strings (for example "foo" + bar), need to be formatted in the arguments
24brace replacement language, (for example "foo{}", bar)
25
26After the script has been run, remember to reformat with clang-format
27
28This script will be removed Q2 2024
29"""
30
31
32SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
33
34files = check_output(
35    ["git", "-C", os.path.join(SCRIPT_DIR, ".."), "grep", "-l", "BMCWEB_LOG_"]
36)
37filenames = files.split(b"\n")
38
39
40for filename in filenames:
41    if not filename:
42        continue
43    with open(filename, "r") as filehandle:
44        contents = filehandle.read()
45
46    # Normalize all the log statements to a single line
47    new_contents = ""
48    replacing = False
49    for line in contents.splitlines():
50        match = re.match(r"\s+BMCWEB_LOG_", line)
51        if match:
52            replacing = True
53
54        if replacing and not match:
55            line = " " + line.lstrip()
56        if line.endswith(";"):
57            replacing = False
58        new_contents += line
59        if not replacing:
60            new_contents += "\n"
61    contents = new_contents
62
63    new_contents = ""
64    for line in contents.splitlines():
65        match = re.match(r"(\s+BMCWEB_LOG_[A-Z]+) <<", line)
66        if match:
67            logstring = ""
68            line = line.lstrip()
69            chevron_split = line.split("<<")
70            arguments = []
71            for log_piece in chevron_split[1:]:
72                if log_piece.endswith(";"):
73                    log_piece = log_piece[:-1]
74                log_piece = log_piece.strip()
75                if (log_piece.startswith('"') and log_piece.endswith('"')) or (
76                    log_piece.startswith("'") and log_piece.endswith("'")
77                ):
78                    logstring += log_piece[1:-1]
79                else:
80                    if log_piece == "this" or log_piece.startswith("&"):
81                        log_piece = "logPtr({})".format(log_piece)
82                    if log_piece == "self":
83                        log_piece = "logPtr(self.get())"
84                    arguments.append(log_piece)
85                    logstring += "{}"
86            if logstring.endswith("\\n"):
87                logstring = logstring[:-2]
88
89            arguments.insert(0, '"' + logstring + '"')
90            argjoin = ", ".join(arguments)
91
92            line = match.group(1) + "(" + argjoin + ");"
93        new_contents += line + "\n"
94
95    contents = new_contents
96
97    with open(filename, "w") as filehandle:
98        filehandle.write(new_contents)
99
100print()
101