Coverage for pyngrok/log.py: 100.00%
31 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-02 23:21 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-02 23:21 +0000
1import logging
2import shlex
3from typing import Optional
5__author__ = "Alex Laird"
6__copyright__ = "Copyright 2023, Alex Laird"
7__version__ = "7.0.0"
10class NgrokLog:
11 """
12 An object containing a parsed log from the ``ngrok`` process.
13 """
15 def __init__(self,
16 line: str) -> None:
17 #: The raw, unparsed log line.
18 self.line: str = line.strip()
20 #: The log's ISO 8601 timestamp.
21 self.t: Optional[str] = None
22 #: The log's level.
23 self.lvl: str = "NOTSET"
24 #: The log's message.
25 self.msg: Optional[str] = None
26 #: The log's error, if applicable.
27 self.err: Optional[str] = None
28 #: The URL, if ``obj`` is "web".
29 self.addr: Optional[str] = None
31 for i in shlex.split(self.line):
32 if "=" not in i:
33 continue
35 key, value = i.split("=", 1)
37 if key == "lvl":
38 if not value:
39 value = self.lvl
41 value = value.upper()
42 if value == "CRIT":
43 value = "CRITICAL"
44 elif value in ["ERR", "EROR"]:
45 value = "ERROR"
46 elif value == "WARN":
47 value = "WARNING"
49 if not hasattr(logging, value):
50 value = self.lvl
52 setattr(self, key, value)
54 def __repr__(self) -> str:
55 return "<NgrokLog: t={} lvl={} msg=\"{}\">".format(self.t, self.lvl, self.msg)
57 def __str__(self) -> str: # pragma: no cover
58 attrs = [attr for attr in dir(self) if not attr.startswith("_") and getattr(self, attr) is not None]
59 attrs.remove("line")
61 return " ".join("{}=\"{}\"".format(attr, getattr(self, attr)) for attr in attrs)