Merge pull request #1230 from nghttp2/nghttpx-faster-logging
nghttpx: Get rid of std::stringstream from Log
This commit is contained in:
commit
4bfc0cd196
|
@ -613,8 +613,8 @@ void ConnectionHandler::handle_ocsp_complete() {
|
||||||
auto status = WEXITSTATUS(rstatus);
|
auto status = WEXITSTATUS(rstatus);
|
||||||
if (ocsp_.error || !WIFEXITED(rstatus) || status != 0) {
|
if (ocsp_.error || !WIFEXITED(rstatus) || status != 0) {
|
||||||
LOG(WARN) << "ocsp query command for " << tls_ctx_data->cert_file
|
LOG(WARN) << "ocsp query command for " << tls_ctx_data->cert_file
|
||||||
<< " failed: error=" << ocsp_.error << ", rstatus=" << std::hex
|
<< " failed: error=" << ocsp_.error << ", rstatus=" << log::hex
|
||||||
<< rstatus << std::dec << ", status=" << status;
|
<< rstatus << log::dec << ", status=" << status;
|
||||||
++ocsp_.next;
|
++ocsp_.next;
|
||||||
proceed_next_cert_ocsp();
|
proceed_next_cert_ocsp();
|
||||||
return;
|
return;
|
||||||
|
|
218
src/shrpx_log.cc
218
src/shrpx_log.cc
|
@ -74,6 +74,44 @@ constexpr const char *SEVERITY_COLOR[] = {
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
#ifndef NOTHREADS
|
||||||
|
# ifdef HAVE_THREAD_LOCAL
|
||||||
|
namespace {
|
||||||
|
thread_local LogBuffer logbuf_;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
LogBuffer *get_logbuf() { return &logbuf_; }
|
||||||
|
} // namespace
|
||||||
|
# else // !HAVE_THREAD_LOCAL
|
||||||
|
namespace {
|
||||||
|
pthread_key_t lckey;
|
||||||
|
pthread_once_t lckey_once = PTHREAD_ONCE_INIT;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void make_key() { pthread_key_create(&lckey, NULL); }
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
LogBuffer *get_logbuf() {
|
||||||
|
pthread_once(&lckey_once, make_key);
|
||||||
|
auto buf = static_cast<LogBuffer *>(pthread_getspecific(lckey));
|
||||||
|
if (!buf) {
|
||||||
|
buf = new LogBuffer();
|
||||||
|
pthread_setspecific(lckey, buf);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
# endif // !HAVE_THREAD_LOCAL
|
||||||
|
#else // NOTHREADS
|
||||||
|
namespace {
|
||||||
|
LogBuffer *get_logbuf() {
|
||||||
|
static LogBuffer logbuf;
|
||||||
|
return &logbuf;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif // NOTHREADS
|
||||||
|
|
||||||
int Log::severity_thres_ = NOTICE;
|
int Log::severity_thres_ = NOTICE;
|
||||||
|
|
||||||
void Log::set_severity_level(int severity) { severity_thres_ = severity; }
|
void Log::set_severity_level(int severity) { severity_thres_ = severity; }
|
||||||
|
@ -106,7 +144,15 @@ int severity_to_syslog_level(int severity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Log(int severity, const char *filename, int linenum)
|
Log::Log(int severity, const char *filename, int linenum)
|
||||||
: filename_(filename), severity_(severity), linenum_(linenum) {}
|
: buf_(*get_logbuf()),
|
||||||
|
begin_(buf_.data()),
|
||||||
|
end_(begin_ + buf_.size()),
|
||||||
|
last_(begin_),
|
||||||
|
filename_(filename),
|
||||||
|
flags_(0),
|
||||||
|
severity_(severity),
|
||||||
|
linenum_(linenum),
|
||||||
|
full_(false) {}
|
||||||
|
|
||||||
Log::~Log() {
|
Log::~Log() {
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -127,12 +173,13 @@ Log::~Log() {
|
||||||
|
|
||||||
if (errorconf.syslog) {
|
if (errorconf.syslog) {
|
||||||
if (severity_ == NOTICE) {
|
if (severity_ == NOTICE) {
|
||||||
syslog(severity_to_syslog_level(severity_), "[%s] %s",
|
syslog(severity_to_syslog_level(severity_), "[%s] %.*s",
|
||||||
SEVERITY_STR[severity_].c_str(), stream_.str().c_str());
|
SEVERITY_STR[severity_].c_str(), static_cast<int>(rleft()),
|
||||||
|
begin_);
|
||||||
} else {
|
} else {
|
||||||
syslog(severity_to_syslog_level(severity_), "[%s] %s (%s:%d)",
|
syslog(severity_to_syslog_level(severity_), "[%s] %.*s (%s:%d)",
|
||||||
SEVERITY_STR[severity_].c_str(), stream_.str().c_str(), filename_,
|
SEVERITY_STR[severity_].c_str(), static_cast<int>(rleft()), begin_,
|
||||||
linenum_);
|
filename_, linenum_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -145,11 +192,11 @@ Log::~Log() {
|
||||||
|
|
||||||
// Error log format: <datetime> <master-pid> <current-pid>
|
// Error log format: <datetime> <master-pid> <current-pid>
|
||||||
// <thread-id> <level> (<filename>:<line>) <msg>
|
// <thread-id> <level> (<filename>:<line>) <msg>
|
||||||
rv = snprintf(buf, sizeof(buf), "%s %d %d %s %s%s%s (%s:%d) %s\n",
|
rv = snprintf(buf, sizeof(buf), "%s %d %d %s %s%s%s (%s:%d) %.*s\n",
|
||||||
lgconf->tstamp->time_iso8601.c_str(), config->pid, lgconf->pid,
|
lgconf->tstamp->time_iso8601.c_str(), config->pid, lgconf->pid,
|
||||||
lgconf->thread_id.c_str(), tty ? SEVERITY_COLOR[severity_] : "",
|
lgconf->thread_id.c_str(), tty ? SEVERITY_COLOR[severity_] : "",
|
||||||
SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "",
|
SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "",
|
||||||
filename_, linenum_, stream_.str().c_str());
|
filename_, linenum_, static_cast<int>(rleft()), begin_);
|
||||||
|
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -161,6 +208,156 @@ Log::~Log() {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(const std::string &s) {
|
||||||
|
write_seq(std::begin(s), std::end(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(const StringRef &s) {
|
||||||
|
write_seq(std::begin(s), std::end(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(const char *s) {
|
||||||
|
write_seq(s, s + strlen(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(const ImmutableString &s) {
|
||||||
|
write_seq(std::begin(s), std::end(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(int64_t n) {
|
||||||
|
if (n >= 0) {
|
||||||
|
return *this << static_cast<uint64_t>(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags_ & fmt_hex) {
|
||||||
|
write_hex(n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
n *= -1;
|
||||||
|
|
||||||
|
size_t nlen = 0;
|
||||||
|
for (auto t = n; t; t /= 10, ++nlen)
|
||||||
|
;
|
||||||
|
if (wleft() < 1 /* sign */ + nlen) {
|
||||||
|
full_ = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
*last_++ = '-';
|
||||||
|
*last_ += nlen;
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
auto p = last_ - 1;
|
||||||
|
for (; n; n /= 10) {
|
||||||
|
*p-- = (n % 10) + '0';
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(uint64_t n) {
|
||||||
|
if (flags_ & fmt_hex) {
|
||||||
|
write_hex(n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
*last_++ = '0';
|
||||||
|
update_full();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
size_t nlen = 0;
|
||||||
|
for (auto t = n; t; t /= 10, ++nlen)
|
||||||
|
;
|
||||||
|
if (wleft() < nlen) {
|
||||||
|
full_ = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_ += nlen;
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
auto p = last_ - 1;
|
||||||
|
for (; n; n /= 10) {
|
||||||
|
*p-- = (n % 10) + '0';
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(double n) {
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto left = wleft();
|
||||||
|
auto rv = snprintf(reinterpret_cast<char *>(last_), left, "%.9f", n);
|
||||||
|
if (rv > static_cast<int>(left)) {
|
||||||
|
full_ = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_ += rv;
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(long double n) {
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto left = wleft();
|
||||||
|
auto rv = snprintf(reinterpret_cast<char *>(last_), left, "%.9Lf", n);
|
||||||
|
if (rv > static_cast<int>(left)) {
|
||||||
|
full_ = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_ += rv;
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(bool n) {
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last_++ = n ? '1' : '0';
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::operator<<(const void *p) {
|
||||||
|
if (full_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_hex(reinterpret_cast<uintptr_t>(p));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace log {
|
||||||
|
void hex(Log &log) { log.set_flags(Log::fmt_hex); };
|
||||||
|
|
||||||
|
void dec(Log &log) { log.set_flags(Log::fmt_dec); };
|
||||||
|
} // namespace log
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
std::pair<OutputIterator, OutputIterator> copy(const char *src, size_t srclen,
|
std::pair<OutputIterator, OutputIterator> copy(const char *src, size_t srclen,
|
||||||
|
@ -696,8 +893,9 @@ void log_chld(pid_t pid, int rstatus, const char *msg) {
|
||||||
|
|
||||||
LOG(NOTICE) << msg << ": [" << pid << "] exited "
|
LOG(NOTICE) << msg << ": [" << pid << "] exited "
|
||||||
<< (WIFEXITED(rstatus) ? "normally" : "abnormally")
|
<< (WIFEXITED(rstatus) ? "normally" : "abnormally")
|
||||||
<< " with status " << std::hex << rstatus << std::oct
|
<< " with status " << log::hex << rstatus << log::dec
|
||||||
<< "; exit status " << WEXITSTATUS(rstatus)
|
<< "; exit status "
|
||||||
|
<< (WIFEXITED(rstatus) ? WEXITSTATUS(rstatus) : 0)
|
||||||
<< (signalstr.empty() ? "" : signalstr.c_str());
|
<< (signalstr.empty() ? "" : signalstr.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
102
src/shrpx_log.h
102
src/shrpx_log.h
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -38,6 +37,7 @@
|
||||||
#include "shrpx_log_config.h"
|
#include "shrpx_log_config.h"
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
using namespace nghttp2;
|
using namespace nghttp2;
|
||||||
|
|
||||||
|
@ -90,26 +90,120 @@ struct DownstreamAddr;
|
||||||
|
|
||||||
enum SeverityLevel { INFO, NOTICE, WARN, ERROR, FATAL };
|
enum SeverityLevel { INFO, NOTICE, WARN, ERROR, FATAL };
|
||||||
|
|
||||||
|
using LogBuffer = std::array<uint8_t, 4_k>;
|
||||||
|
|
||||||
class Log {
|
class Log {
|
||||||
public:
|
public:
|
||||||
Log(int severity, const char *filename, int linenum);
|
Log(int severity, const char *filename, int linenum);
|
||||||
~Log();
|
~Log();
|
||||||
template <typename Type> Log &operator<<(Type s) {
|
Log &operator<<(const std::string &s);
|
||||||
stream_ << s;
|
Log &operator<<(const char *s);
|
||||||
|
Log &operator<<(const StringRef &s);
|
||||||
|
Log &operator<<(const ImmutableString &s);
|
||||||
|
Log &operator<<(int16_t n) { return *this << static_cast<int64_t>(n); }
|
||||||
|
Log &operator<<(int32_t n) { return *this << static_cast<int64_t>(n); }
|
||||||
|
Log &operator<<(int64_t n);
|
||||||
|
Log &operator<<(uint16_t n) { return *this << static_cast<uint64_t>(n); }
|
||||||
|
Log &operator<<(uint32_t n) { return *this << static_cast<uint64_t>(n); }
|
||||||
|
Log &operator<<(uint64_t n);
|
||||||
|
Log &operator<<(float n) { return *this << static_cast<double>(n); }
|
||||||
|
Log &operator<<(double n);
|
||||||
|
Log &operator<<(long double n);
|
||||||
|
Log &operator<<(bool n);
|
||||||
|
Log &operator<<(const void *p);
|
||||||
|
template <typename T> Log &operator<<(const std::shared_ptr<T> &ptr) {
|
||||||
|
return *this << ptr.get();
|
||||||
|
}
|
||||||
|
Log &operator<<(void (*func)(Log &log)) {
|
||||||
|
func(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
template <typename InputIt> void write_seq(InputIt first, InputIt last) {
|
||||||
|
if (full_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto d = std::distance(first, last);
|
||||||
|
auto n = std::min(wleft(), static_cast<size_t>(d));
|
||||||
|
last_ = std::copy(first, first + n, last_);
|
||||||
|
update_full();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void write_hex(T n) {
|
||||||
|
if (full_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
if (wleft() < 4 /* for "0x00" */) {
|
||||||
|
full_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*last_++ = '0';
|
||||||
|
*last_++ = 'x';
|
||||||
|
*last_++ = '0';
|
||||||
|
*last_++ = '0';
|
||||||
|
update_full();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nlen = 0;
|
||||||
|
for (auto t = n; t; t >>= 8, ++nlen)
|
||||||
|
;
|
||||||
|
|
||||||
|
nlen *= 2;
|
||||||
|
|
||||||
|
if (wleft() < 2 /* for "0x" */ + nlen) {
|
||||||
|
full_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last_++ = '0';
|
||||||
|
*last_++ = 'x';
|
||||||
|
|
||||||
|
last_ += nlen;
|
||||||
|
update_full();
|
||||||
|
|
||||||
|
auto p = last_ - 1;
|
||||||
|
for (; n; n >>= 8) {
|
||||||
|
uint8_t b = n & 0xff;
|
||||||
|
*p-- = util::LOWER_XDIGITS[b & 0xf];
|
||||||
|
*p-- = util::LOWER_XDIGITS[b >> 4];
|
||||||
|
}
|
||||||
|
}
|
||||||
static void set_severity_level(int severity);
|
static void set_severity_level(int severity);
|
||||||
static int set_severity_level_by_name(const StringRef &name);
|
static int set_severity_level_by_name(const StringRef &name);
|
||||||
static bool log_enabled(int severity) { return severity >= severity_thres_; }
|
static bool log_enabled(int severity) { return severity >= severity_thres_; }
|
||||||
|
|
||||||
|
enum {
|
||||||
|
fmt_dec = 0x00,
|
||||||
|
fmt_hex = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_flags(int flags) { flags_ = flags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::stringstream stream_;
|
size_t rleft() { return last_ - begin_; }
|
||||||
|
size_t wleft() { return end_ - last_; }
|
||||||
|
void update_full() { full_ = last_ == end_; }
|
||||||
|
|
||||||
|
LogBuffer &buf_;
|
||||||
|
uint8_t *begin_;
|
||||||
|
uint8_t *end_;
|
||||||
|
uint8_t *last_;
|
||||||
const char *filename_;
|
const char *filename_;
|
||||||
|
uint32_t flags_;
|
||||||
int severity_;
|
int severity_;
|
||||||
int linenum_;
|
int linenum_;
|
||||||
|
bool full_;
|
||||||
static int severity_thres_;
|
static int severity_thres_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace log {
|
||||||
|
void hex(Log &log);
|
||||||
|
void dec(Log &log);
|
||||||
|
} // namespace log
|
||||||
|
|
||||||
#define TTY_HTTP_HD (log_config()->errorlog_tty ? "\033[1;34m" : "")
|
#define TTY_HTTP_HD (log_config()->errorlog_tty ? "\033[1;34m" : "")
|
||||||
#define TTY_RST (log_config()->errorlog_tty ? "\033[0m" : "")
|
#define TTY_RST (log_config()->errorlog_tty ? "\033[0m" : "")
|
||||||
|
|
||||||
|
|
|
@ -591,7 +591,7 @@ int sct_add_cb(SSL *ssl, unsigned int ext_type, unsigned int context,
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "sct_add_cb is called, chainidx=" << chainidx << ", x=" << x
|
LOG(INFO) << "sct_add_cb is called, chainidx=" << chainidx << ", x=" << x
|
||||||
<< ", context=" << std::hex << context;
|
<< ", context=" << log::hex << context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only have SCTs for leaf certificate.
|
// We only have SCTs for leaf certificate.
|
||||||
|
@ -1856,7 +1856,7 @@ void try_cache_tls_session(TLSSessionCache *cache, SSL_SESSION *session,
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "Update client cache entry "
|
LOG(INFO) << "Update client cache entry "
|
||||||
<< "timestamp = " << std::fixed << std::setprecision(6) << t;
|
<< "timestamp = " << t;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->session_data = serialize_ssl_session(session);
|
cache->session_data = serialize_ssl_session(session);
|
||||||
|
|
Loading…
Reference in New Issue