diff --git a/src/shrpx_log.cc b/src/shrpx_log.cc index e1d8f2ad..f9ccf568 100644 --- a/src/shrpx_log.cc +++ b/src/shrpx_log.cc @@ -163,51 +163,48 @@ Log::~Log() { namespace { template -std::pair copy(const char *src, size_t srclen, - size_t avail, OutputIterator oitr) { - auto nwrite = std::min(srclen, avail); - auto noitr = std::copy_n(src, nwrite, oitr); - return std::make_pair(noitr, avail - nwrite); +std::pair copy(const char *src, size_t srclen, + OutputIterator d_first, + OutputIterator d_last) { + auto nwrite = + std::min(static_cast(std::distance(d_first, d_last)), srclen); + return std::make_pair(std::copy_n(src, nwrite, d_first), d_last); } } // namespace namespace { template -std::pair copy(const char *src, size_t avail, - OutputIterator oitr) { - return copy(src, strlen(src), avail, oitr); +std::pair +copy(const char *src, OutputIterator d_first, OutputIterator d_last) { + return copy(src, strlen(src), d_first, d_last); } } // namespace namespace { template -std::pair copy(const std::string &src, size_t avail, - OutputIterator oitr) { - return copy(src.c_str(), src.size(), avail, oitr); -} -} // namespace - -namespace { -template -std::pair copy(const StringRef &src, size_t avail, - OutputIterator oitr) { - return copy(src.c_str(), src.size(), avail, oitr); -} -} // namespace - -namespace { -template -std::pair copy(const ImmutableString &src, size_t avail, - OutputIterator oitr) { - return copy(src.c_str(), src.size(), avail, oitr); +std::pair +copy(const StringRef &src, OutputIterator d_first, OutputIterator d_last) { + return copy(src.c_str(), src.size(), d_first, d_last); } } // namespace namespace { template -std::pair copy_l(const char (&src)[N], size_t avail, - OutputIterator oitr) { - return copy(src, N - 1, avail, oitr); +std::pair +copy_l(const char (&src)[N], OutputIterator d_first, OutputIterator d_last) { + return copy(src, N - 1, d_first, d_last); +} +} // namespace + +namespace { +template +std::pair copy(char c, OutputIterator d_first, + OutputIterator d_last) { + if (d_first == d_last) { + return std::make_pair(d_last, d_last); + } + *d_first++ = c; + return std::make_pair(d_first, d_last); } } // namespace @@ -217,15 +214,29 @@ const char LOWER_XDIGITS[] = "0123456789abcdef"; namespace { template -std::pair copy_hex_low(const uint8_t *src, - size_t srclen, size_t avail, - OutputIterator oitr) { - auto nwrite = std::min(srclen * 2, avail) / 2; - for (auto i = 0u; i < nwrite; ++i) { - *oitr++ = LOWER_XDIGITS[src[i] >> 4]; - *oitr++ = LOWER_XDIGITS[src[i] & 0xf]; +std::pair +copy_hex_low(const uint8_t *src, size_t srclen, OutputIterator d_first, + OutputIterator d_last) { + auto nwrite = std::min(static_cast(std::distance(d_first, d_last)), + srclen * 2) / + 2; + for (size_t i = 0; i < nwrite; ++i) { + *d_first++ = LOWER_XDIGITS[src[i] >> 4]; + *d_first++ = LOWER_XDIGITS[src[i] & 0xf]; } - return std::make_pair(oitr, avail - nwrite); + return std::make_pair(d_first, d_last); +} +} // namespace + +namespace { +template +std::pair copy(T n, OutputIterator d_first, + OutputIterator d_last) { + if (static_cast(std::distance(d_first, d_last)) < + str_size("18446744073709551615")) { + return std::make_pair(d_last, d_last); + } + return std::make_pair(util::utos(d_first, n), d_last); } } // namespace @@ -277,7 +288,7 @@ void upstream_accesslog(const std::vector &lfv, return; } - char buf[4_k]; + std::array buf; auto downstream = lgsp.downstream; @@ -298,132 +309,129 @@ void upstream_accesslog(const std::vector &lfv, : StringRef::from_lit("-") : req.path; - auto p = buf; - auto avail = sizeof(buf) - 2; + auto p = std::begin(buf); + auto last = std::end(buf) - 2; for (auto &lf : lfv) { switch (lf.type) { case SHRPX_LOGF_LITERAL: - std::tie(p, avail) = copy(lf.value, avail, p); + std::tie(p, last) = copy(lf.value, p, last); break; case SHRPX_LOGF_REMOTE_ADDR: - std::tie(p, avail) = copy(lgsp.remote_addr, avail, p); + std::tie(p, last) = copy(lgsp.remote_addr, p, last); break; case SHRPX_LOGF_TIME_LOCAL: - std::tie(p, avail) = copy(tstamp->time_local, avail, p); + std::tie(p, last) = copy(tstamp->time_local, p, last); break; case SHRPX_LOGF_TIME_ISO8601: - std::tie(p, avail) = copy(tstamp->time_iso8601, avail, p); + std::tie(p, last) = copy(tstamp->time_iso8601, p, last); break; case SHRPX_LOGF_REQUEST: - std::tie(p, avail) = copy(method, avail, p); - std::tie(p, avail) = copy_l(" ", avail, p); - std::tie(p, avail) = copy(path, avail, p); - std::tie(p, avail) = copy_l(" HTTP/", avail, p); - std::tie(p, avail) = copy(util::utos(req.http_major), avail, p); + std::tie(p, last) = copy(method, p, last); + std::tie(p, last) = copy(' ', p, last); + std::tie(p, last) = copy(path, p, last); + std::tie(p, last) = copy_l(" HTTP/", p, last); + std::tie(p, last) = copy(req.http_major, p, last); if (req.http_major < 2) { - std::tie(p, avail) = copy_l(".", avail, p); - std::tie(p, avail) = copy(util::utos(req.http_minor), avail, p); + std::tie(p, last) = copy('.', p, last); + std::tie(p, last) = copy(req.http_minor, p, last); } break; case SHRPX_LOGF_STATUS: - std::tie(p, avail) = copy(util::utos(resp.http_status), avail, p); + std::tie(p, last) = copy(resp.http_status, p, last); break; case SHRPX_LOGF_BODY_BYTES_SENT: - std::tie(p, avail) = - copy(util::utos(downstream->response_sent_body_length), avail, p); + std::tie(p, last) = copy(downstream->response_sent_body_length, p, last); break; case SHRPX_LOGF_HTTP: { auto hd = req.fs.header(lf.value); if (hd) { - std::tie(p, avail) = copy((*hd).value, avail, p); + std::tie(p, last) = copy((*hd).value, p, last); break; } - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } case SHRPX_LOGF_AUTHORITY: if (!req.authority.empty()) { - std::tie(p, avail) = copy(req.authority, avail, p); + std::tie(p, last) = copy(req.authority, p, last); break; } - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; case SHRPX_LOGF_REMOTE_PORT: - std::tie(p, avail) = copy(lgsp.remote_port, avail, p); + std::tie(p, last) = copy(lgsp.remote_port, p, last); break; case SHRPX_LOGF_SERVER_PORT: - std::tie(p, avail) = copy(util::utos(lgsp.server_port), avail, p); + std::tie(p, last) = copy(lgsp.server_port, p, last); break; case SHRPX_LOGF_REQUEST_TIME: { auto t = std::chrono::duration_cast( lgsp.request_end_time - downstream->get_request_start_time()) .count(); - - auto frac = util::utos(t % 1000); - auto sec = util::utos(t / 1000); - if (frac.size() < 3) { - frac = std::string(3 - frac.size(), '0') + frac; + std::tie(p, last) = copy(t / 1000, p, last); + std::tie(p, last) = copy('.', p, last); + auto frac = t % 1000; + if (frac < 100) { + auto n = frac < 10 ? 2 : 1; + std::tie(p, last) = copy("000", n, p, last); } - sec += '.'; - sec += frac; - - std::tie(p, avail) = copy(sec, avail, p); - } break; + std::tie(p, last) = copy(frac, p, last); + break; + } case SHRPX_LOGF_PID: - std::tie(p, avail) = copy(util::utos(lgsp.pid), avail, p); + std::tie(p, last) = copy(lgsp.pid, p, last); break; case SHRPX_LOGF_ALPN: - std::tie(p, avail) = copy(lgsp.alpn, avail, p); + std::tie(p, last) = copy(lgsp.alpn, p, last); break; case SHRPX_LOGF_SSL_CIPHER: if (!lgsp.tls_info) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = copy(lgsp.tls_info->cipher, avail, p); + std::tie(p, last) = copy(lgsp.tls_info->cipher, p, last); break; case SHRPX_LOGF_SSL_PROTOCOL: if (!lgsp.tls_info) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = copy(lgsp.tls_info->protocol, avail, p); + std::tie(p, last) = copy(lgsp.tls_info->protocol, p, last); break; case SHRPX_LOGF_SSL_SESSION_ID: if (!lgsp.tls_info || lgsp.tls_info->session_id_length == 0) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = - copy_hex_low(lgsp.tls_info->session_id, - lgsp.tls_info->session_id_length, avail, p); + std::tie(p, last) = copy_hex_low( + lgsp.tls_info->session_id, lgsp.tls_info->session_id_length, p, last); break; case SHRPX_LOGF_SSL_SESSION_REUSED: if (!lgsp.tls_info) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = - copy_l(lgsp.tls_info->session_reused ? "r" : ".", avail, p); + std::tie(p, last) = + copy(lgsp.tls_info->session_reused ? 'r' : '.', p, last); break; case SHRPX_LOGF_BACKEND_HOST: if (!downstream_addr) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = copy(downstream_addr->host, avail, p); + std::tie(p, last) = copy(downstream_addr->host, p, last); break; case SHRPX_LOGF_BACKEND_PORT: if (!downstream_addr) { - std::tie(p, avail) = copy_l("-", avail, p); + std::tie(p, last) = copy('-', p, last); break; } - std::tie(p, avail) = copy(util::utos(downstream_addr->port), avail, p); + std::tie(p, last) = copy(downstream_addr->port, p, last); break; case SHRPX_LOGF_NONE: break; @@ -435,15 +443,16 @@ void upstream_accesslog(const std::vector &lfv, *p = '\0'; if (accessconf.syslog) { - syslog(LOG_INFO, "%s", buf); + syslog(LOG_INFO, "%s", buf.data()); return; } *p++ = '\n'; - auto nwrite = p - buf; - while (write(lgconf->accesslog_fd, buf, nwrite) == -1 && errno == EINTR) + auto nwrite = std::distance(std::begin(buf), p); + while (write(lgconf->accesslog_fd, buf.data(), nwrite) == -1 && + errno == EINTR) ; }