From 7fe6993f2b2b014f52a3c7638e1cf5f57fc5c92e Mon Sep 17 00:00:00 2001 From: ziyi chen Date: Wed, 16 Nov 2022 14:45:13 -0500 Subject: [PATCH] add logger-level option --- src/common/BUILD.bazel | 15 +++++++ src/common/include/logging_level_utils.h | 18 +++++++++ src/common/logging_level_utils.cpp | 50 ++++++++++++++++++++++++ src/main/BUILD.bazel | 1 + src/main/database.cpp | 12 ++++++ src/main/include/database.h | 4 +- tools/python_api/include/py_database.h | 4 ++ tools/python_api/kuzu_binding.cpp | 10 ++++- tools/python_api/py_database.cpp | 3 +- tools/python_api/test/conftest.py | 10 ++--- tools/python_api/test/example.py | 11 +++--- tools/python_api/test/test_df.py | 10 +++++ tools/shell/embedded_shell.cpp | 18 ++++++++- tools/shell/include/embedded_shell.h | 2 + 14 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 src/common/include/logging_level_utils.h create mode 100644 src/common/logging_level_utils.cpp diff --git a/src/common/BUILD.bazel b/src/common/BUILD.bazel index 4f94a5adaa..a799a61142 100644 --- a/src/common/BUILD.bazel +++ b/src/common/BUILD.bazel @@ -226,3 +226,18 @@ cc_library( ], visibility = ["//visibility:public"], ) + +cc_library( + name = "logging_level_util", + srcs = [ + "logging_level_utils.cpp", + ], + hdrs = [ + "include/logging_level_utils.h", + ], + visibility = ["//visibility:public"], + deps = [ + "utils", + "@gabime_spdlog", + ], +) diff --git a/src/common/include/logging_level_utils.h b/src/common/include/logging_level_utils.h new file mode 100644 index 0000000000..6533624d72 --- /dev/null +++ b/src/common/include/logging_level_utils.h @@ -0,0 +1,18 @@ +#pragma once + +#include "spdlog/spdlog.h" + +using namespace std; + +namespace kuzu { +namespace common { + +class LoggingLevelUtils { +public: + static spdlog::level::level_enum convertStrToLevelEnum(string loggingLevel); + + static string convertLevelEnumToStr(spdlog::level::level_enum levelEnum); +}; + +} // namespace common +} // namespace kuzu diff --git a/src/common/logging_level_utils.cpp b/src/common/logging_level_utils.cpp new file mode 100644 index 0000000000..6928d7b476 --- /dev/null +++ b/src/common/logging_level_utils.cpp @@ -0,0 +1,50 @@ +#include "src/common/include/logging_level_utils.h" + +#include "src/common/include/utils.h" + +namespace kuzu { +namespace common { + +spdlog::level::level_enum LoggingLevelUtils::convertStrToLevelEnum(string loggingLevel) { + StringUtils::toLower(loggingLevel); + if (loggingLevel == "info") { + return spdlog::level::level_enum::info; + } else if (loggingLevel == "debug") { + return spdlog::level::level_enum::debug; + } else if (loggingLevel == "err") { + return spdlog::level::level_enum::err; + } + throw ConversionException( + StringUtils::string_format("Unsupported logging level: %s.", loggingLevel.c_str())); +} + +string LoggingLevelUtils::convertLevelEnumToStr(spdlog::level::level_enum levelEnum) { + switch (levelEnum) { + case spdlog::level::level_enum::trace: { + return "trace"; + } + case spdlog::level::level_enum::debug: { + return "debug"; + } + case spdlog::level::level_enum::info: { + return "info"; + } + case spdlog::level::level_enum::warn: { + return "warn"; + } + case spdlog::level::level_enum::err: { + return "err"; + } + case spdlog::level::level_enum::critical: { + return "critical"; + } + case spdlog::level::level_enum::off: { + return "off"; + } + default: + assert(false); + } +} + +} // namespace common +} // namespace kuzu diff --git a/src/main/BUILD.bazel b/src/main/BUILD.bazel index 77aa229aa1..013dfaf863 100644 --- a/src/main/BUILD.bazel +++ b/src/main/BUILD.bazel @@ -13,6 +13,7 @@ cc_library( ], deps = [ "//src/binder", + "//src/common:logging_level_util", "//src/parser", "//src/planner:enumerator", "//src/processor", diff --git a/src/main/database.cpp b/src/main/database.cpp index 89b7ddeee2..84239543d9 100644 --- a/src/main/database.cpp +++ b/src/main/database.cpp @@ -3,6 +3,7 @@ #include "spdlog/spdlog.h" #include "src/common/include/configs.h" +#include "src/common/include/logging_level_utils.h" #include "src/storage/include/wal_replayer.h" namespace kuzu { @@ -58,6 +59,17 @@ void Database::initLoggers() { spdlog::set_level(spdlog::level::err); } +void Database::setLoggingLevel(spdlog::level::level_enum loggingLevel) { + if (loggingLevel != spdlog::level::level_enum::debug && + loggingLevel != spdlog::level::level_enum::info && + loggingLevel != spdlog::level::level_enum::err) { + printf("Unsupported logging level: %s.", + LoggingLevelUtils::convertLevelEnumToStr(loggingLevel).c_str()); + return; + } + spdlog::set_level(loggingLevel); +} + void Database::resizeBufferManager(uint64_t newSize) { systemConfig.defaultPageBufferPoolSize = newSize * StorageConfig::DEFAULT_PAGES_BUFFER_RATIO; systemConfig.largePageBufferPoolSize = newSize * StorageConfig::LARGE_PAGES_BUFFER_RATIO; diff --git a/src/main/include/database.h b/src/main/include/database.h index 60a1669c05..a147f3e550 100644 --- a/src/main/include/database.h +++ b/src/main/include/database.h @@ -55,10 +55,12 @@ class Database { explicit Database(const DatabaseConfig& databaseConfig, const SystemConfig& systemConfig); - ~Database() = default; + void setLoggingLevel(spdlog::level::level_enum loggingLevel); void resizeBufferManager(uint64_t newSize); + ~Database() = default; + private: // TODO(Semih): This is refactored here for now to be able to test transaction behavior // in absence of the frontend support. Consider moving this code to connection.cpp. diff --git a/tools/python_api/include/py_database.h b/tools/python_api/include/py_database.h index 8f3a388f38..0ae098401b 100644 --- a/tools/python_api/include/py_database.h +++ b/tools/python_api/include/py_database.h @@ -10,6 +10,10 @@ class PyDatabase { friend class PyConnection; public: + inline void setLoggingLevel(spdlog::level::level_enum logging_level) { + database->setLoggingLevel(logging_level); + } + static void initialize(py::handle& m); explicit PyDatabase(const string& databasePath, uint64_t bufferPoolSize); diff --git a/tools/python_api/kuzu_binding.cpp b/tools/python_api/kuzu_binding.cpp index 7a22c44032..c32fbb3dc0 100644 --- a/tools/python_api/kuzu_binding.cpp +++ b/tools/python_api/kuzu_binding.cpp @@ -1,8 +1,16 @@ #include "include/py_connection.h" #include "include/py_database.h" -#include "include/py_query_result_converter.h" + +void bindEnumTypes(py::module& m) { + py::enum_(m, "loggingLevel") + .value("debug", spdlog::level::level_enum::debug) + .value("info", spdlog::level::level_enum::info) + .value("err", spdlog::level::level_enum::err) + .export_values(); +} void bind(py::module& m) { + bindEnumTypes(m); PyDatabase::initialize(m); PyConnection::initialize(m); PyQueryResult::initialize(m); diff --git a/tools/python_api/py_database.cpp b/tools/python_api/py_database.cpp index 278a13b045..b854b1a936 100644 --- a/tools/python_api/py_database.cpp +++ b/tools/python_api/py_database.cpp @@ -4,7 +4,8 @@ void PyDatabase::initialize(py::handle& m) { py::class_(m, "database") .def(py::init(), py::arg("database_path"), py::arg("buffer_pool_size") = 0) - .def("resize_buffer_manager", &PyDatabase::resizeBufferManager, py::arg("new_size")); + .def("resize_buffer_manager", &PyDatabase::resizeBufferManager, py::arg("new_size")) + .def("set_logging_level", &PyDatabase::setLoggingLevel, py::arg("logging_level")); } PyDatabase::PyDatabase(const string& databasePath, uint64_t bufferPoolSize) { diff --git a/tools/python_api/test/conftest.py b/tools/python_api/test/conftest.py index 3378314ee6..2060a56a4a 100644 --- a/tools/python_api/test/conftest.py +++ b/tools/python_api/test/conftest.py @@ -2,7 +2,7 @@ import pytest -from tools.python_api import _kuzu as gdb +from tools.python_api import _kuzu as kuzu # Note conftest is the default file name for sharing fixture through multiple test files. Do not change file name. @@ -11,8 +11,8 @@ def init_tiny_snb(tmp_path): if os.path.exists(tmp_path): os.rmdir(tmp_path) output_path = str(tmp_path) - db = gdb.database(output_path) - conn = gdb.connection(db) + db = kuzu.database(output_path) + conn = kuzu.connection(db) conn.execute("CREATE NODE TABLE person (ID INT64, fName STRING, gender INT64, isStudent BOOLEAN, isWorker BOOLEAN, " "age INT64, eyeSight DOUBLE, birthdate DATE, registerTime TIMESTAMP, lastJobDuration " "INTERVAL, workedHours INT64[], usedNames STRING[], courseScoresPerTerm INT64[][], PRIMARY " @@ -27,6 +27,6 @@ def init_tiny_snb(tmp_path): @pytest.fixture def establish_connection(init_tiny_snb): - db = gdb.database(init_tiny_snb, buffer_pool_size=256 * 1024 * 1024) - conn = gdb.connection(db, num_threads=4) + db = kuzu.database(init_tiny_snb, buffer_pool_size=256 * 1024 * 1024) + conn = kuzu.connection(db, num_threads=4) return conn, db diff --git a/tools/python_api/test/example.py b/tools/python_api/test/example.py index 5646df6944..9bf73f4d01 100644 --- a/tools/python_api/test/example.py +++ b/tools/python_api/test/example.py @@ -1,11 +1,10 @@ -from tools.python_api import _kuzu as gdb +from tools.python_api import _kuzu as kuzu - -databaseDir = "path_to_serialized_database" -db = gdb.database(databaseDir) -conn = gdb.connection(db) +databaseDir = "path to database file" +db = kuzu.database(databaseDir) +conn = kuzu.connection(db) query = "MATCH (a:person) RETURN *;" -result = conn.query(query) +result = conn.execute(query) while result.hasNext(): print(result.getNext()) result.close() diff --git a/tools/python_api/test/test_df.py b/tools/python_api/test/test_df.py index 6219128554..ab5692c99f 100644 --- a/tools/python_api/test/test_df.py +++ b/tools/python_api/test/test_df.py @@ -1,6 +1,7 @@ import numpy as np from pandas import Timestamp, Timedelta, isna +from tools.python_api import _kuzu as kuzu def test_to_df(establish_connection): @@ -77,3 +78,12 @@ def _test_to_df(conn): db.resize_buffer_manager(512 * 1024 * 1024) conn.set_max_threads_for_exec(4) _test_to_df(conn) + + db.set_logging_level(kuzu.loggingLevel.debug) + _test_to_df(conn) + + db.set_logging_level(kuzu.loggingLevel.info) + _test_to_df(conn) + + db.set_logging_level(kuzu.loggingLevel.err) + _test_to_df(conn) diff --git a/tools/shell/embedded_shell.cpp b/tools/shell/embedded_shell.cpp index 0a4a6d10d4..f45a34a401 100644 --- a/tools/shell/embedded_shell.cpp +++ b/tools/shell/embedded_shell.cpp @@ -4,6 +4,7 @@ #include #include +#include "src/common/include/logging_level_utils.h" #include "src/common/include/type_utils.h" namespace kuzu { @@ -27,8 +28,9 @@ struct ShellCommand { const string LIST_RELS = ":list_rels"; const string SHOW_NODE = ":show_node"; const string SHOW_REL = ":show_rel"; + const string LOGGING_LEVEL = ":logging_level"; const vector commandList = {HELP, CLEAR, QUIT, THREAD, BUFFER_MANAGER_SIZE, - BUFFER_MANAGER_DEBUG_INFO, LIST_NODES, LIST_RELS, SHOW_NODE, SHOW_REL}; + BUFFER_MANAGER_DEBUG_INFO, LIST_NODES, LIST_RELS, SHOW_NODE, SHOW_REL, LOGGING_LEVEL}; } shellCommand; const char* TAB = " "; @@ -207,6 +209,8 @@ void EmbeddedShell::run() { printNodeSchema(lineStr.substr(shellCommand.SHOW_NODE.length())); } else if (lineStr.rfind(shellCommand.SHOW_REL) == 0) { printRelSchema(lineStr.substr(shellCommand.SHOW_REL.length())); + } else if (lineStr.rfind(shellCommand.LOGGING_LEVEL) == 0) { + setLoggingLevel(lineStr.substr(shellCommand.LOGGING_LEVEL.length())); } else if (!lineStr.empty()) { ss.clear(); ss.str(lineStr); @@ -286,6 +290,9 @@ void EmbeddedShell::printHelp() { shellCommand.THREAD.c_str(), TAB); printf("%s%s [bm_size_in_bytes] %sset buffer manager size in bytes\n", TAB, shellCommand.BUFFER_MANAGER_SIZE.c_str(), TAB); + printf("%s%s [logging_level] %sset logging level of database, available options: debug, info, " + "err\n", + TAB, shellCommand.LOGGING_LEVEL.c_str(), TAB); printf("%s%s %slist all node tables\n", TAB, shellCommand.LIST_NODES.c_str(), TAB); printf("%s%s %slist all rel tables\n", TAB, shellCommand.LIST_RELS.c_str(), TAB); printf("%s%s %s[table_name] show node schema\n", TAB, shellCommand.SHOW_NODE.c_str(), TAB); @@ -360,5 +367,14 @@ void EmbeddedShell::printExecutionResult(QueryResult& queryResult) const { } } +void EmbeddedShell::setLoggingLevel(const string& loggingLevel) { + auto level = ltrim(loggingLevel); + try { + auto logLevelEnum = LoggingLevelUtils::convertStrToLevelEnum(level); + database->setLoggingLevel(logLevelEnum); + printf("logging level has been set to: %s.\n", level.c_str()); + } catch (ConversionException& e) { printf("%s", e.what()); } +} + } // namespace main } // namespace kuzu diff --git a/tools/shell/include/embedded_shell.h b/tools/shell/include/embedded_shell.h index 3f1ad98990..e99fc318ad 100644 --- a/tools/shell/include/embedded_shell.h +++ b/tools/shell/include/embedded_shell.h @@ -31,6 +31,8 @@ class EmbeddedShell { void updateTableNames(); + void setLoggingLevel(const string& loggingLevel); + private: unique_ptr database; unique_ptr conn;