From f8b4aa3cdfc1d61ec94df49763176755fc05163e Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Mon, 18 Jul 2011 15:51:16 -0700 Subject: [PATCH] ProfLogger: write out length of message first Write out the length of the message first, so that it's easier to write clients. Also, serialize ProfLogger instances to memory rather than directly to the socket, to avoid blocking while holding one of the ProfLogger locks. Signed-off-by: Colin McCabe --- src/common/ProfLogger.cc | 64 +++++++++++++++++++++++++--------------- src/common/ProfLogger.h | 2 +- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/common/ProfLogger.cc b/src/common/ProfLogger.cc index 8e3c1b23bf2ee..58321868aa8e2 100644 --- a/src/common/ProfLogger.cc +++ b/src/common/ProfLogger.cc @@ -151,8 +151,7 @@ public: if (fds[0].revents & POLLOUT) { // Send out some data - if (!do_accept()) - return PFL_FAIL; + do_accept(); } if (fds[1].revents & POLLIN) { // Parent wants us to shut down @@ -166,6 +165,7 @@ private: bool do_accept() { + int ret; struct sockaddr_un address; socklen_t address_length; int connection_fd = accept(m_sock_fd, (struct sockaddr*) &address, @@ -176,30 +176,39 @@ private: << cpp_strerror(err) << dendl; return false; } - FILE *fp = fdopen(m_sock_fd, "w"); - if (!fp) { - int err = errno; - lderr(m_parent->m_cct) << "ProfLogThread: failed to fdopen '" - << m_sock_fd << "'. error " << cpp_strerror(err) << dendl; - close(connection_fd); - return false; - } - fprintf(fp, "{"); + std::vector buffer; + buffer.reserve(512); { Mutex::Locker lck(m_parent->m_lock); // Take lock to access m_loggers - for (std::set ::iterator log = m_parent->m_loggers.begin(); - log != m_parent->m_loggers.end(); ++log) + buffer.push_back('{'); + buffer.push_back(' '); + for (std::set ::iterator l = m_parent->m_loggers.begin(); + l != m_parent->m_loggers.end(); ++l) { - // This will take the logger's lock for short period of time, - // then release it. - (*log)->write_json_to_fp(fp); + (*l)->write_json_to_buf(buffer); } + buffer.push_back('}'); + buffer.push_back('\0'); + } + + uint32_t len = htonl(buffer.size()); + ret = safe_write(connection_fd, &len, sizeof(len)); + if (ret < 0) { + lderr(m_parent->m_cct) << "ProfLogThread: error writing message size: " + << cpp_strerror(ret) << dendl; + close(connection_fd); + return false; + } + ret = safe_write(connection_fd, &buffer[0], buffer.size()); + if (ret < 0) { + lderr(m_parent->m_cct) << "ProfLogThread: error writing message: " + << cpp_strerror(ret) << dendl; + close(connection_fd); + return false; } - fprintf(fp, "}"); - fflush(fp); - fclose(fp); // calls close(connection_fd) + close(connection_fd); return true; } @@ -417,23 +426,25 @@ fget(int idx) } void ProfLogger:: -write_json_to_fp(FILE *fp) +write_json_to_buf(std::vector &buffer) { + char buf[512]; Mutex::Locker lck(m_lock); prof_log_data_vec_t::const_iterator d = m_data.begin(); prof_log_data_vec_t::const_iterator d_end = m_data.end(); for (; d != d_end; ++d) { const prof_log_data_any_d &data(*d); + buf[0] = '\0'; if (d->count != COUNT_DISABLED) { switch (d->type) { case PROF_LOG_DATA_ANY_U64: - fprintf(fp, "\"%s\" : { \"count\" : %" PRId64 ", " + snprintf(buf, sizeof(buf), "\"%s\" : { \"count\" : %" PRId64 ", " "\"sum\" : %" PRId64 " },\n", data.name, data.count, data.u.u64); break; case PROF_LOG_DATA_ANY_DOUBLE: - fprintf(fp, "\"%s\" : { \"count\" : %" PRId64 ", " + snprintf(buf, sizeof(buf), "\"%s\" : { \"count\" : %" PRId64 ", " "\"sum\" : %g },\n", data.name, data.count, data.u.dbl); break; @@ -445,16 +456,21 @@ write_json_to_fp(FILE *fp) else { switch (d->type) { case PROF_LOG_DATA_ANY_U64: - fprintf(fp, "\"%s\" : %" PRId64 ",\n", data.name, data.u.u64); + snprintf(buf, sizeof(buf), "\"%s\" : %" PRId64 ",\n", + data.name, data.u.u64); break; case PROF_LOG_DATA_ANY_DOUBLE: - fprintf(fp, "\"%s\" : %g,\n", data.name, data.u.dbl); + snprintf(buf, sizeof(buf), "\"%s\" : %g,\n", data.name, data.u.dbl); break; default: assert(0); break; } } + size_t strlen_buf = strlen(buf); + std::vector::size_type sz = buffer.size(); + buffer.resize(sz + strlen_buf); + memcpy(&buffer[sz], buf, strlen_buf); } } diff --git a/src/common/ProfLogger.h b/src/common/ProfLogger.h index 7847b4fc5c519..15004a98b54ad 100644 --- a/src/common/ProfLogger.h +++ b/src/common/ProfLogger.h @@ -71,7 +71,7 @@ public: void finc(int idx, double v); double fget(int idx); - void write_json_to_fp(FILE *fp); + void write_json_to_buf(std::vector &buffer); private: ProfLogger(CephContext *cct, const std::string &name, -- 2.39.5