Skip to content

Commit

Permalink
Add logger class
Browse files Browse the repository at this point in the history
  • Loading branch information
christoph2 committed Nov 7, 2024
1 parent 1a88620 commit 1879042
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 80 deletions.
12 changes: 7 additions & 5 deletions pya2l/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ def import_a2l(
``AML`` and ``IF_DATA`` sections are currently not processed.
"""
a2l_parser = A2LParser()
db = a2l_parser.parse(file_name=file_name, local=local, in_memory=in_memory, encoding=encoding, remove_existing=remove_existing)
db = a2l_parser.parse(
file_name=file_name, local=local, in_memory=in_memory, encoding=encoding, remove_existing=remove_existing, loglevel=loglevel
)
session = db.session

# self.logger.info("Parsing AML section ...")
Expand Down Expand Up @@ -140,7 +142,7 @@ def parse_aml(file_name: str) -> bytes:
return session


def open_existing(file_name: str):
def open_existing(file_name: str, loglevel: str = "INFO"):
"""Open an existing `.a2ldb` database.
Parameters
Expand Down Expand Up @@ -180,7 +182,7 @@ def open_create(file_name: str, local: bool = False, encoding: str = "", logleve
if not db_fn.exists():
return import_a2l(a2l_fn, local=local, encoding=encoding, loglevel=loglevel)
else:
return open_existing(db_fn)
return open_existing(db_fn, loglevel)


def export_a2l(db_name: str, output: typing.Union[TextIOWrapper, str, typing.Any] = sys.stdout, encoding="latin1"): # noqa: UP007
Expand Down Expand Up @@ -223,8 +225,8 @@ def import_a2l(
return import_a2l(file_name, debug, in_memory, remove_existing, local, encoding, loglevel)

@staticmethod
def open_existing(file_name: str):
return open_existing(file_name)
def open_existing(file_name: str, loglevel: str = "INFO"):
return open_existing(file_name, loglevel)

@staticmethod
def open_create(file_name: str, local: bool = False, encoding: str = "", loglevel: str = "INFO"):
Expand Down
23 changes: 19 additions & 4 deletions pya2l/a2lparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ class A2LParser:
def __init__(self):
self.debug = False
self.logger = Logger("A2LDB", "INFO")
# self.logger.setLevel("ERROR")

def __del__(self):
pass
Expand All @@ -325,8 +324,23 @@ def close(self):
pass

def parse(
self, file_name: str, encoding: str = "latin-1", in_memory: bool = False, local: bool = False, remove_existing: bool = False
self,
file_name: str,
encoding: str = "latin-1",
in_memory: bool = False,
local: bool = False,
remove_existing: bool = False,
loglevel: str = "INFO",
):
LEVEL_MAP = {
"INFO": ext.LogLevel.INFO,
"WARN": ext.LogLevel.WARNING,
"ERROR": ext.LogLevel.ERROR,
"DEBUG": ext.LogLevel.DEBUG,
"CRITICAL": ext.LogLevel.CRITICAL,
}
self.silent = loglevel.upper() == "CRITICAL"
ext.set_log_level(LEVEL_MAP.get(loglevel.upper()))
a2l_fn, db_fn = path_components(in_memory, file_name, local)
if not in_memory:
if remove_existing:
Expand Down Expand Up @@ -357,7 +371,8 @@ def parse(
TimeRemainingColumn(),
)
self.progress_bar = Progress(*progress_columns)
self.task = self.progress_bar.add_task("[blue]writing to DB...", total=keyword_counter)
if not self.silent:
self.task = self.progress_bar.add_task("[blue]writing to DB...", total=keyword_counter)
self.advance = keyword_counter // 100 if keyword_counter >= 100 else 1
fr = FakeRoot()
with self.progress_bar:
Expand All @@ -374,7 +389,7 @@ def traverse(self, tree, parent, attr, multiple, level=0):
name = tree.get_name()

# print("TABLE ==> ", name, parent, multiple)
if self.counter % self.advance == 0:
if not self.silent and self.counter % self.advance == 0:
self.db.session.flush()
self.progress_bar.update(self.task, advance=self.advance)
# db.session.commit()
Expand Down
35 changes: 21 additions & 14 deletions pya2l/a2lparser_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ namespace py = pybind11;

std::string ValueContainer::s_encoding{ "ascii" };

Logger logger{};


void set_log_level(LogLevel level) {
logger.setLevel(level);
}

auto parse(const std::string& file_name, const std::string& encoding) -> std::tuple<std::size_t, const ValueContainer> {
Preprocessor p{ "INFO" };

Expand All @@ -19,16 +26,16 @@ auto parse(const std::string& file_name, const std::string& encoding) -> std::tu
auto& [fns, linemap, ifdr] = res;
p.finalize();
std::chrono::steady_clock::time_point stop1 = std::chrono::steady_clock::now();
std::cout << "[Info (pya2l.Preprocessor)] Elapsed Time: " << (std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()) / 1000.0 << "[s]" << std::endl;
logger.info("Elapsed Time: ", (std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()) / 1000.0, "[s]");

std::cout << "[Info (pya2l.A2LParser)] Parsing intermediate file: " << fns.a2l << std::endl;
logger.info("Parsing intermediate file: ", fns.a2l);
std::chrono::steady_clock::time_point start2 = std::chrono::steady_clock::now();
auto parser = A2LParser(res, fns.a2l, encoding);
auto counter = parser.get_keyword_counter();
const auto& values = parser.get_values();
std::chrono::steady_clock::time_point stop2 = std::chrono::steady_clock::now();
std::cout << "[Info (pya2l.A2LParser)] Elapsed Time: " << (std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()) / 1000.0 << "[s]" << std::endl;
std::cout << "[Info (pya2l.A2LParser)] Number of keywords: " << counter << std::endl;
logger.info("Elapsed Time: ", (std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()) / 1000.0, "[s]");
logger.info("Number of keywords: ", counter);

return {counter, values};
}
Expand All @@ -39,8 +46,17 @@ struct Overload : Ts... {
};

PYBIND11_MODULE(a2lparser_ext, m) {
m.def("parse", &parse, py::return_value_policy::move)
m.def("parse", &parse, py::return_value_policy::move);
m.def("set_log_level", &set_log_level);

py::enum_<LogLevel>(m, "LogLevel")
.value("DEBUG", LogLevel::DEBUG)
.value("INFO", LogLevel::INFO)
.value("WARNING", LogLevel::WARNING)
.value("ERROR", LogLevel::ERROR)
.value("CRITICAL", LogLevel::CRITICAL)
;

py::class_<ValueContainer>(m, "ValueContainer")
.def(py::init<std::string_view>(), py::arg("name"))
.def("get_name", &ValueContainer::get_name)
Expand Down Expand Up @@ -109,12 +125,3 @@ PYBIND11_MODULE(a2lparser_ext, m) {
return result;
});
}

#if 0
m.def("return_bytes",
[]() {
std::string s("\xba\xd0\xba\xd0"); // Not valid UTF-8
return py::bytes(s); // Return the data without transcoding
}
);
#endif
34 changes: 11 additions & 23 deletions pya2l/extensions/a2lparser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class A2LParser {
m_value_stack.push(&m_root);
m_idr = std::make_unique<IfDataReader>(std::get<2>(prepro_result.value()));
m_table_count = 0;
m_logger = Logger("pya2l.A2LParser", LogLevel::DEBUG);
logger.setName("pya2l.A2LParser");
parse(file_name, encoding);
}

Expand Down Expand Up @@ -73,12 +73,6 @@ class A2LParser {

if (token_type() == A2LTokenType::BEGIN) {
m_reader->consume();
#if 0
if (kw_tos().contains(token_type())) {
} else {
std::cout << "Warning: unexpected token: " << token->toString() << std::endl;
}
#endif
}

// TODO: Factor out.
Expand All @@ -96,9 +90,7 @@ class A2LParser {

if (token->getType() == ANTLRToken::_EOF) {
if (std::size(m_kw_stack) > 1) {
std::cout << "[ERROR (pya2l.A2LParser)] " << "Premature end of file!!!\n";
} else {
// std::cout << "OK, done.\n";
logger.error("Premature end of file!!!");
}
break;
}
Expand All @@ -112,30 +104,24 @@ class A2LParser {
//
// TODO: Addressmapper
auto kwt = kw_tos();
std::cerr << "[ERROR (pya2l.A2LParser)] Invalid token: " << token->toString() << std::endl;
m_logger.error("Invalid token: ", token->toString());
logger.error("Invalid token: ", token->toString());
if ((token->getText() == "IF_DATA") && (kwt.m_name == "ROOT")) {
std::cerr << "[ERROR (pya2l.A2LParser)] No top-level PROJECT element. This is probably an include file?\n";
m_logger.error("No top-level PROJECT element. This is probably an include file?");
logger.error("No top-level PROJECT element. This is probably an include file?");
}
break;
}

if (token->getText() == "IF_DATA") {
// std::cout << "\tID: " << token->getLine() << ":" << token->column() << std::endl;
if (m_prepro_result) {
if_data_section = m_idr->get({ token->getLine(), token->column() + 1 });
if (if_data_section) {
// std::cout << "\t FOUND IF_DATA!!!\n";
}
}
}
m_reader->consume();
m_keyword_counter++;
auto kw = ValueContainer(kw_tos().m_name);

// std::cout << "KW: " << kw_tos().m_name << std::endl;

auto [p, m] = do_parameters();
value_tos().set_parameters(std::move(p));
value_tos().set_multiple_values(std::move(m));
Expand Down Expand Up @@ -190,12 +176,14 @@ class A2LParser {
((token_type() == A2LTokenType::END) && (parameter.is_multiple() == false))) {
// Not all parameters are present.

std::cerr << "[WARNING (pya2l.A2LParser)] " << kw_tos().m_name << " is missing one or more required parameters: " << std::endl;
// std::cerr << "[WARNING (pya2l.A2LParser)] " << kw_tos().m_name << " is missing one or more required parameters: " << std::endl;
logger.error(kw_tos().m_name, " is missing one or more required parameters: ");

for (std::size_t idx = param_count; idx < std::size(kw_tos().m_parameters); ++idx) {
auto p = kw_tos().m_parameters[idx];

std::cerr << "\t" << p.get_name() << std::endl;
//std::cerr << "\t" << p.get_name() << std::endl;
logger.error("\t", p.get_name());

switch (p.get_type()) {
case PredefinedType::Int:
Expand Down Expand Up @@ -227,7 +215,8 @@ class A2LParser {
tuple_parser.feed(token);
if (tuple_parser.get_state() == ParameterTupleParser::StateType::FINISHED) {
if (!std::holds_alternative<std::string>(parameter_list[0])) {
std::cerr << "[ERROR (pya2l.A2LParser)] " << "Invalid tuple.\n";
//std::cerr << "[ERROR (pya2l.A2LParser)] " << "Invalid tuple.\n";
logger.error("Invalid tuple.");
break;
}
m_tables.push_back({ value_tos().get_name(), std::get<std::string>(parameter_list[0]),
Expand Down Expand Up @@ -260,7 +249,7 @@ class A2LParser {

const auto valid = validate(parameter, token, value);
if (!valid) {
std::cout << "[ERROR (pya2l.A2LParser)] " << "Invalid param: " << parameter.get_name() << " -- " << token->toString() << std::endl;
logger.error("Invalid param: ", parameter.get_name(), " -- ", token->toString());
}

if (parameter.is_multiple() == true) {
Expand Down Expand Up @@ -311,7 +300,6 @@ class A2LParser {
std::vector<value_table_t> m_tables;
std::size_t m_table_count{ 0 };
bool m_finalized{ false };
Logger m_logger;
};

#endif // __A2LPARSER_HPP
3 changes: 2 additions & 1 deletion pya2l/extensions/ifdata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <cstdio>

#include "tokenizer.hpp"
#include "logger.hpp"

using line_type = std::tuple< std::size_t, std::size_t>;

Expand Down Expand Up @@ -191,7 +192,7 @@ class IfDataReader : public IfDataBase {
}

if (offset >= m_size) {
std::cerr << "[ERROR (pya2l.IF_DATAParser)] " << "file offset " << offset << " is out of range of file size " << m_size << std::endl;
logger.error("file offset ", offset, " is out of range of file size ", m_size);
return std::nullopt;
} else {
// std::cout << "file offset: " << offset << std::endl;
Expand Down
45 changes: 35 additions & 10 deletions pya2l/extensions/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,49 +32,73 @@ class Logger {

Logger(const std::string& name="", LogLevel level=LogLevel::INFO) : m_name(name), m_level(level) {
}
Logger(const Logger&) = default;
Logger(Logger&&) = default;
Logger& operator=(const Logger &) = default;
Logger& operator=(Logger&&) = default;

Logger(const Logger& other) {
m_name = other.m_name;
m_level = other.m_level;
}

Logger(Logger&& other) {
m_name = other.m_name;
m_level = std::move(other.m_level);
}

Logger& operator=(const Logger & other) {
m_name = other.m_name;
m_level = other.m_level;
}

Logger& operator=(Logger&& other) {
m_name = other.m_name;
m_level = std::move(other.m_level);
}

void setLevel(LogLevel level) noexcept {
m_level = level;
}

void setName(const std::string& name) {
m_name = name;
}

template<typename ...Args>
constexpr void log(LogLevel level, Args&&... args) noexcept {
std::cout << "[" << loglevel_to_string(level) << " (" << m_name << ")]";
std::cout << "[" << loglevel_to_string(level) << " (" << m_name << ")] ";
((std::cout << std::forward<Args>(args) << " "), ...);
std::cout << std::endl;
}

template<typename ...Args>
constexpr void debug(Args&&... args) noexcept {
if (LogLevel::DEBUG <= m_level) {
if (LogLevel::DEBUG > m_level) {
log(LogLevel::DEBUG, args ...);
}
}

template<typename ...Args>
constexpr void info(Args&&... args) noexcept {
if (LogLevel::INFO <= m_level) {
if (LogLevel::INFO > m_level) {
log(LogLevel::INFO, args ...);
}
}

template<typename ...Args>
constexpr void warn(Args&&... args) noexcept {
if (LogLevel::WARNING <= m_level) {
if (LogLevel::WARNING > m_level) {
log(LogLevel::WARNING, args ...);
}
}

template<typename ...Args>
constexpr void error(Args&&... args) noexcept {
if (LogLevel::ERROR <= m_level) {
if (LogLevel::ERROR > m_level) {
log(LogLevel::ERROR, args ...);
}
}

template<typename ...Args>
constexpr void critical(Args&&... args) noexcept {
if (LogLevel::CRITICAL <= m_level) {
if (LogLevel::CRITICAL > m_level) {
log(LogLevel::CRITICAL, args ...);
}
}
Expand All @@ -85,5 +109,6 @@ class Logger {
LogLevel m_level;
};

extern Logger logger;

#endif // __LOGGER_HPP
Loading

0 comments on commit 1879042

Please sign in to comment.