-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathlogging.cpp
More file actions
88 lines (71 loc) · 2.77 KB
/
Copy pathlogging.cpp
File metadata and controls
88 lines (71 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* Copyright 2023 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
#include "logging.h"
#include <lagrange/Logger.h>
#include <lagrange/python/binding.h>
// clang-format off
#include <lagrange/utils/warnoff.h>
#include <spdlog/sinks/base_sink.h>
#include <lagrange/utils/warnon.h>
// clang-format on
#include <mutex>
namespace nb = nanobind;
namespace lagrange::python {
namespace {
class PythonLoggingSink : public spdlog::sinks::base_sink<std::mutex>
{
public:
PythonLoggingSink(std::string logger_name)
{
nb::module_ logging = nb::module_::import_("logging");
m_py_logger = logging.attr("getLogger")(logger_name);
}
protected:
void sink_it_(const spdlog::details::log_msg& msg) override
{
// Logging in python requires the current thread to hold the GIL.
if (!NB_CALL(gil_check)()) return;
auto payload = msg.payload;
auto res = nb::str(payload.data(), payload.size());
switch (msg.level) {
case spdlog::level::trace: m_py_logger.attr("debug")(res); break;
case spdlog::level::debug: m_py_logger.attr("debug")(res); break;
case spdlog::level::info: m_py_logger.attr("info")(res); break;
case spdlog::level::warn: m_py_logger.attr("warning")(res); break;
case spdlog::level::err: m_py_logger.attr("error")(res); break;
case spdlog::level::critical: m_py_logger.attr("critical")(res); break;
case spdlog::level::off: break;
default: break;
}
}
void flush_() override
{
// Logging in python requires the current thread to hold the GIL.
if (!NB_CALL(gil_check)()) return;
auto handlers = m_py_logger.attr("handlers");
for (auto handler : handlers) {
handler.attr("flush")();
}
}
private:
nanobind::object m_py_logger;
};
} // namespace
void register_python_logger(nanobind::module_& m)
{
auto& logger = lagrange::logger();
std::string logger_name = nb::cast<std::string>(m.attr("__name__"));
logger.sinks().clear();
logger.sinks().emplace_back(std::make_shared<PythonLoggingSink>(std::move(logger_name)));
logger.set_level(spdlog::level::trace); // Log level will be controlled by Python.
}
} // namespace lagrange::python