2020#include < rcl/rcl.h>
2121#include < rcl_logging_interface/rcl_logging_interface.h>
2222
23+ #include < mutex>
2324#include < string>
2425
2526#include " macros.h"
@@ -40,6 +41,47 @@ Napi::Value InitRosoutPublisherForNode(const Napi::CallbackInfo& info) {
4041 .ThrowAsJavaScriptException ();
4142 rcl_reset_error ();
4243 }
44+ }
45+ return env.Undefined ();
46+ }
47+
48+ static std::recursive_mutex logging_mutex;
49+
50+ static void rclnodejs_thread_safe_logging_output_handler (
51+ const rcutils_log_location_t * location, int severity, const char * name,
52+ rcutils_time_point_value_t timestamp, const char * format, va_list* args) {
53+ try {
54+ std::lock_guard<std::recursive_mutex> lock (logging_mutex);
55+ rcl_logging_multiple_output_handler (location, severity, name, timestamp,
56+ format, args);
57+ } catch (const std::exception& ex) {
58+ RCUTILS_SAFE_FWRITE_TO_STDERR (
59+ " rclnodejs failed to get the global logging mutex: " );
60+ RCUTILS_SAFE_FWRITE_TO_STDERR (ex.what ());
61+ RCUTILS_SAFE_FWRITE_TO_STDERR (" \n " );
62+ } catch (...) {
63+ RCUTILS_SAFE_FWRITE_TO_STDERR (
64+ " rclnodejs failed to get the global logging mutex\n " );
65+ }
66+ }
67+
68+ Napi::Value LoggingConfigure (const Napi::CallbackInfo& info) {
69+ Napi::Env env = info.Env ();
70+ RclHandle* context_handle = RclHandle::Unwrap (info[0 ].As <Napi::Object>());
71+ rcl_context_t * context =
72+ reinterpret_cast <rcl_context_t *>(context_handle->ptr ());
73+
74+ rcl_allocator_t allocator = rcl_get_default_allocator ();
75+
76+ std::lock_guard<std::recursive_mutex> lock (logging_mutex);
77+ rcl_ret_t ret = rcl_logging_configure_with_output_handler (
78+ &context->global_arguments , &allocator,
79+ rclnodejs_thread_safe_logging_output_handler);
80+
81+ if (ret != RCL_RET_OK ) {
82+ Napi::Error::New (env, rcl_get_error_string ().str )
83+ .ThrowAsJavaScriptException ();
84+ rcl_reset_error ();
4385 }
4486 return env.Undefined ();
4587}
@@ -60,6 +102,18 @@ Napi::Value FiniRosoutPublisherForNode(const Napi::CallbackInfo& info) {
60102 return env.Undefined ();
61103}
62104
105+ Napi::Value LoggingFini (const Napi::CallbackInfo& info) {
106+ Napi::Env env = info.Env ();
107+ std::lock_guard<std::recursive_mutex> lock (logging_mutex);
108+ rcl_ret_t ret = rcl_logging_fini ();
109+ if (ret != RCL_RET_OK ) {
110+ Napi::Error::New (env, rcl_get_error_string ().str )
111+ .ThrowAsJavaScriptException ();
112+ rcl_reset_error ();
113+ }
114+ return env.Undefined ();
115+ }
116+
63117Napi::Value setLoggerLevel (const Napi::CallbackInfo& info) {
64118 Napi::Env env = info.Env ();
65119
@@ -192,6 +246,8 @@ Napi::Object InitLoggingBindings(Napi::Env env, Napi::Object exports) {
192246 exports.Set (" removeRosoutSublogger" ,
193247 Napi::Function::New (env, RemoveRosoutSublogger));
194248#endif
249+ exports.Set (" loggingConfigure" , Napi::Function::New (env, LoggingConfigure));
250+ exports.Set (" loggingFini" , Napi::Function::New (env, LoggingFini));
195251 return exports;
196252}
197253
0 commit comments