diff --git a/include/mp/proxy-io.h b/include/mp/proxy-io.h index 367a9beb..ddbad43a 100644 --- a/include/mp/proxy-io.h +++ b/include/mp/proxy-io.h @@ -130,6 +130,16 @@ class Logger std::ostringstream m_buffer; }; +struct LogOptions { + + //! External logging callback. + LogFn log_fn; + + //! Maximum number of characters to use when representing + //! request and response structs as strings. + size_t max_chars{200}; +}; + std::string LongThreadName(const char* exe_name); //! Event loop implementation. @@ -204,12 +214,12 @@ class EventLoop Logger log() { - Logger logger(false, m_log_fn); + Logger logger(false, m_log_opts.log_fn); logger << "{" << LongThreadName(m_exe_name) << "} "; return logger; } - Logger logPlain() { return {false, m_log_fn}; } - Logger raise() { return {true, m_log_fn}; } + Logger logPlain() { return {false, m_log_opts.log_fn}; } + Logger raise() { return {true, m_log_opts.log_fn}; } //! Process name included in thread names so combined debug output from //! multiple processes is easier to understand. @@ -255,8 +265,8 @@ class EventLoop //! List of connections. std::list m_incoming_connections; - //! External logging callback. - LogFn m_log_fn; + //! Logging options + LogOptions m_log_opts; //! External context pointer. void* m_context; diff --git a/include/mp/proxy-types.h b/include/mp/proxy-types.h index de96d134..cacddb3a 100644 --- a/include/mp/proxy-types.h +++ b/include/mp/proxy-types.h @@ -631,13 +631,13 @@ void clientInvoke(ProxyClient& proxy_client, const GetRequest& get_request, Fiel IterateFields().handleChain(*invoke_context, request, FieldList(), typename FieldObjs::BuildParams{&fields}...); proxy_client.m_context.loop->logPlain() << "{" << thread_context.thread_name << "} IPC client send " - << TypeName() << " " << LogEscape(request.toString()); + << TypeName() << " " << LogEscape(request.toString(), proxy_client.m_context.loop->m_log_opts.max_chars); proxy_client.m_context.loop->m_task_set->add(request.send().then( [&](::capnp::Response&& response) { proxy_client.m_context.loop->logPlain() << "{" << thread_context.thread_name << "} IPC client recv " - << TypeName() << " " << LogEscape(response.toString()); + << TypeName() << " " << LogEscape(response.toString(), proxy_client.m_context.loop->m_log_opts.max_chars); try { IterateFields().handleChain( *invoke_context, response, FieldList(), typename FieldObjs::ReadResults{&fields}...); @@ -701,7 +701,7 @@ kj::Promise serverInvoke(Server& server, CallContext& call_context, Fn fn) int req = ++server_reqs; server.m_context.loop->log() << "IPC server recv request #" << req << " " - << TypeName() << " " << LogEscape(params.toString()); + << TypeName() << " " << LogEscape(params.toString(), server.m_context.loop->m_log_opts.max_chars); try { using ServerContext = ServerInvokeContext; @@ -718,7 +718,7 @@ kj::Promise serverInvoke(Server& server, CallContext& call_context, Fn fn) [&]() { return kj::Promise(kj::mv(call_context)); }) .then([&server, req](CallContext call_context) { server.m_context.loop->log() << "IPC server send response #" << req << " " << TypeName() - << " " << LogEscape(call_context.getResults().toString()); + << " " << LogEscape(call_context.getResults().toString(), server.m_context.loop->m_log_opts.max_chars); }); } catch (const std::exception& e) { server.m_context.loop->log() << "IPC server unhandled exception: " << e.what(); diff --git a/include/mp/util.h b/include/mp/util.h index d9f3ca3e..978130cf 100644 --- a/include/mp/util.h +++ b/include/mp/util.h @@ -203,7 +203,7 @@ std::string ThreadName(const char* exe_name); //! Escape binary string for use in log so it doesn't trigger unicode decode //! errors in python unit tests. -std::string LogEscape(const kj::StringTree& string); +std::string LogEscape(const kj::StringTree& string, size_t max_size); //! Callback type used by SpawnProcess below. using FdToArgsFn = std::function(int fd)>; diff --git a/src/mp/proxy.cpp b/src/mp/proxy.cpp index c9fecf5c..263908a0 100644 --- a/src/mp/proxy.cpp +++ b/src/mp/proxy.cpp @@ -187,9 +187,9 @@ EventLoop::EventLoop(const char* exe_name, LogFn log_fn, void* context) : m_exe_name(exe_name), m_io_context(kj::setupAsyncIo()), m_task_set(new kj::TaskSet(m_error_handler)), - m_log_fn(std::move(log_fn)), m_context(context) { + m_log_opts.log_fn = log_fn; int fds[2]; KJ_SYSCALL(socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); m_wait_fd = fds[0]; diff --git a/src/mp/util.cpp b/src/mp/util.cpp index da7c3b0b..b7124622 100644 --- a/src/mp/util.cpp +++ b/src/mp/util.cpp @@ -76,12 +76,11 @@ std::string ThreadName(const char* exe_name) return std::move(buffer).str(); } -std::string LogEscape(const kj::StringTree& string) +std::string LogEscape(const kj::StringTree& string, size_t max_size) { - const int MAX_SIZE = 1000; std::string result; string.visit([&](const kj::ArrayPtr& piece) { - if (result.size() > MAX_SIZE) return; + if (result.size() > max_size) return; for (const char c : piece) { if (c == '\\') { result.append("\\\\"); @@ -92,7 +91,7 @@ std::string LogEscape(const kj::StringTree& string) } else { result.push_back(c); } - if (result.size() > MAX_SIZE) { + if (result.size() > max_size) { result += "..."; break; }