Skip to content

Commit

Permalink
[Refactor] Refactor logging system (#181)
Browse files Browse the repository at this point in the history
This PR refactors and simplifies the logging system by providing a tracing function and deletes the internal error class.
  • Loading branch information
Ubospica authored Feb 4, 2025
1 parent 9d9455d commit 7545396
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 40 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Build Python bindings: ${XGRAMMAR_BUILD_PYTHON_BINDINGS}")
message(STATUS "Build C++ tests: ${XGRAMMAR_BUILD_CXX_TESTS}")
message(STATUS "CUDA architectures: ${XGRAMMAR_CUDA_ARCHITECTURES}")
message(STATUS "Enable C++ trace: ${XGRAMMAR_ENABLE_CPPTRACE}")

if(MSVC)
set(CMAKE_CXX_FLAGS "/Wall ${CMAKE_CXX_FLAGS}")
Expand Down Expand Up @@ -69,6 +70,9 @@ target_include_directories(xgrammar PUBLIC ${XGRAMMAR_INCLUDE_PATH})
if(XGRAMMAR_ENABLE_CPPTRACE)
add_subdirectory(${PROJECT_SOURCE_DIR}/3rdparty/cpptrace)
target_link_libraries(xgrammar PUBLIC cpptrace::cpptrace)
target_compile_definitions(xgrammar PUBLIC XGRAMMAR_ENABLE_CPPTRACE=1)
else()
target_compile_definitions(xgrammar PUBLIC XGRAMMAR_ENABLE_CPPTRACE=0)
endif()

if(XGRAMMAR_BUILD_PYTHON_BINDINGS)
Expand Down
3 changes: 3 additions & 0 deletions cpp/pybind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ target_include_directories(xgrammar_bindings PUBLIC ${XGRAMMAR_INCLUDE_PATH})

if(XGRAMMAR_ENABLE_CPPTRACE)
target_link_libraries(xgrammar_bindings PUBLIC cpptrace::cpptrace)
target_compile_definitions(xgrammar_bindings PUBLIC XGRAMMAR_ENABLE_CPPTRACE=1)
else()
target_compile_definitions(xgrammar_bindings PUBLIC XGRAMMAR_ENABLE_CPPTRACE=0)
endif()

set(LIB_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/python/xgrammar")
Expand Down
20 changes: 20 additions & 0 deletions cpp/support/cpptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,31 @@
#ifndef XGRAMMAR_SUPPORT_CPPTRACE_H_
#define XGRAMMAR_SUPPORT_CPPTRACE_H_

#if XGRAMMAR_ENABLE_CPPTRACE == 1
#include <cpptrace/cpptrace.hpp>
#endif

#include <string>

namespace xgrammar {

#if XGRAMMAR_ENABLE_CPPTRACE == 1

// Flag to check if cpptrace feature is enabled
static constexpr bool CPPTRACE_ENABLED = true;

inline void PrintTrace() { cpptrace::generate_trace().print(); }
inline std::string GetTraceString() { return cpptrace::generate_trace().to_string(true); }

#else

static constexpr bool CPPTRACE_ENABLED = false;

// Provide empty implementation when cpptrace is disabled
inline void PrintTrace() {}
inline std::string GetTraceString() { return ""; }

#endif

} // namespace xgrammar

Expand Down
10 changes: 6 additions & 4 deletions cpp/support/logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@
* \file xgrammar/support/logging.cc
*/
#include "logging.h"
#if (XGRAMMAR_LOG_CUSTOMIZE == 0)

namespace xgrammar {

#if XGRAMMAR_LOG_CUSTOMIZE == 0

LogFatal::Entry& LogFatal::GetEntry() {
static thread_local LogFatal::Entry result;
return result;
}

const char* LogMessage::level_strings_[] = {
": Debug: ", // XGRAMMAR_LOG_LEVEL_DEBUG
": ", // XGRAMMAR_LOG_LEVEL_INFO
": Debug: ", // XGRAMMAR_LOG_LEVEL_DEBUG
": Warning: ", // XGRAMMAR_LOG_LEVEL_WARNING
": Error: ", // XGRAMMAR_LOG_LEVEL_ERROR
};

} // namespace xgrammar
#endif // XGRAMMAR_LOG_CUSTOMIZE

} // namespace xgrammar
45 changes: 11 additions & 34 deletions cpp/support/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,27 @@

namespace xgrammar {

/*!
* \brief exception class that will be thrown by
* default logger
*/
struct Error : public std::runtime_error {
/*!
* \brief constructor
* \param s the error message
*/
explicit Error(const std::string& s) : std::runtime_error(s) {}
};

/*!
* \brief Error type for errors from XGRAMMAR_CHECK, XGRAMMAR_ICHECK, and XGRAMMAR_LOG(FATAL). This
* error contains a backtrace of where it occurred.
*/
class InternalError : public Error {
class Error : public std::runtime_error {
public:
/*! \brief Construct an error. Not recommended to use directly. Instead use XGRAMMAR_LOG(FATAL).
*
* \param file The file where the error occurred.
* \param lineno The line number where the error occurred.
* \param message The error message to display.
* \param time The time at which the error occurred. This should be in local time.
* \param backtrace Backtrace from when the error occurred.
*/
InternalError(
std::string file, int lineno, std::string message, std::time_t time = std::time(nullptr)
)
: Error(""), file_(file), lineno_(lineno), message_(message), time_(time) {
Error(std::string file, int lineno, std::string message, std::time_t time = std::time(nullptr))
: std::runtime_error(""), file_(file), lineno_(lineno), message_(message), time_(time) {
std::ostringstream s;
// XXX: Do not change this format, otherwise all error handling in python will break (because it
// parses the message to reconstruct the error type).
// TODO(tkonolige): Convert errors to Objects, so we can avoid the mess of formatting/parsing
// error messages correctly.
s << "[" << std::put_time(std::localtime(&time), "%H:%M:%S") << "] " << file << ":" << lineno
<< ": " << message << std::endl;
full_message_ = s.str();
}

/*! \return The file in which the error occurred. */
const std::string& file() const { return file_; }
/*! \return The message associated with this error. */
Expand Down Expand Up @@ -171,10 +153,7 @@ class LogFatal {
this->lineno_ = lineno;
}
[[noreturn]] Error Finalize() noexcept(false) {
InternalError error(file_, lineno_, stream_.str());
#if DMLC_LOG_BEFORE_THROW
std::cerr << error.what() << std::endl;
#endif
Error error(file_, lineno_, stream_.str());
throw error;
}
std::ostringstream stream_;
Expand Down Expand Up @@ -204,19 +183,17 @@ class LogMessage {
static const char* level_strings_[];
};

#endif // if XGRAMMAR_LOG_CUSTOMIZE
#endif // XGRAMMAR_LOG_CUSTOMIZE

#define XGRAMMAR_LOG_LEVEL_DEBUG 0
#define XGRAMMAR_LOG_LEVEL_INFO 1
#define XGRAMMAR_LOG_LEVEL_INFO 0
#define XGRAMMAR_LOG_LEVEL_DEBUG 1
#define XGRAMMAR_LOG_LEVEL_WARNING 2
#define XGRAMMAR_LOG_LEVEL_ERROR 3
#define XGRAMMAR_LOG_LEVEL_FATAL 4
#define XGRAMMAR_LOG_LEVEL_FATAL 3

#define XGRAMMAR_LOG_DEBUG LogMessage(__FILE__, __LINE__, XGRAMMAR_LOG_LEVEL_DEBUG).stream()
#define XGRAMMAR_LOG_FATAL LogFatal(__FILE__, __LINE__).stream()
#define XGRAMMAR_LOG_INFO LogMessage(__FILE__, __LINE__, XGRAMMAR_LOG_LEVEL_INFO).stream()
#define XGRAMMAR_LOG_ERROR LogMessage(__FILE__, __LINE__, XGRAMMAR_LOG_LEVEL_ERROR).stream()
#define XGRAMMAR_LOG_DEBUG LogMessage(__FILE__, __LINE__, XGRAMMAR_LOG_LEVEL_DEBUG).stream()
#define XGRAMMAR_LOG_WARNING LogMessage(__FILE__, __LINE__, XGRAMMAR_LOG_LEVEL_WARNING).stream()
#define XGRAMMAR_LOG_FATAL LogFatal(__FILE__, __LINE__).stream()

#define XGRAMMAR_LOG(level) XGRAMMAR_LOG_##level

Expand Down
3 changes: 1 addition & 2 deletions web/src/xgrammar_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ namespace xgrammar {

void LogMessageImpl(const std::string& file, int lineno, int level, const std::string& message) {
static const char* level_strings_[] = {
"[DEBUG] ",
"[INFO] ",
"[DEBUG] ",
"[WARNING] ",
"[ERROR] ",
};
std::cout << level_strings_[level] << file << ":" << lineno << ": " << message << std::endl;
}
Expand Down

0 comments on commit 7545396

Please sign in to comment.