nghttpx: Optimize logging further

This commit is contained in:
Tatsuhiro Tsujikawa 2016-01-17 15:04:09 +09:00
parent 4f07db8bcb
commit 7b2d4b6ae6
6 changed files with 59 additions and 23 deletions

View File

@ -542,7 +542,8 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
} }
if (literal_start < var_start) { if (literal_start < var_start) {
res.emplace_back(SHRPX_LOGF_LITERAL, strcopy(literal_start, var_start)); res.emplace_back(SHRPX_LOGF_LITERAL,
ImmutableString(literal_start, var_start));
} }
literal_start = p; literal_start = p;
@ -552,17 +553,18 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
continue; continue;
} }
res.emplace_back(type, strcopy(value, var_name + var_namelen)); auto name = std::string(value, var_name + var_namelen);
auto &v = res.back().value; for (auto &c : name) {
for (size_t i = 0; v[i]; ++i) { if (c == '_') {
if (v[i] == '_') { c = '-';
v[i] = '-';
}
} }
} }
res.emplace_back(type, ImmutableString(name));
}
if (literal_start != eop) { if (literal_start != eop) {
res.emplace_back(SHRPX_LOGF_LITERAL, strcopy(literal_start, eop)); res.emplace_back(SHRPX_LOGF_LITERAL, ImmutableString(literal_start, eop));
} }
return res; return res;

View File

@ -224,8 +224,8 @@ void Downstream::force_resume_read() {
} }
namespace { namespace {
const Headers::value_type *get_header_linear(const Headers &headers, const Headers::value_type *search_header_linear(const Headers &headers,
const std::string &name) { const StringRef &name) {
const Headers::value_type *res = nullptr; const Headers::value_type *res = nullptr;
for (auto &kv : headers) { for (auto &kv : headers) {
if (kv.name == name) { if (kv.name == name) {
@ -395,8 +395,8 @@ Headers::value_type *FieldStore::header(int16_t token) {
return http2::get_header(hdidx_, token, headers_); return http2::get_header(hdidx_, token, headers_);
} }
const Headers::value_type *FieldStore::header(const std::string &name) const { const Headers::value_type *FieldStore::header(const StringRef &name) const {
return get_header_linear(headers_, name); return search_header_linear(headers_, name);
} }
void FieldStore::add_header(std::string name, std::string value) { void FieldStore::add_header(std::string name, std::string value) {

View File

@ -76,7 +76,7 @@ public:
Headers::value_type *header(int16_t token); Headers::value_type *header(int16_t token);
// Returns pointer to the header field with the name |name|. If no // Returns pointer to the header field with the name |name|. If no
// such header is found, returns nullptr. // such header is found, returns nullptr.
const Headers::value_type *header(const std::string &name) const; const Headers::value_type *header(const StringRef &name) const;
void add_header(std::string name, std::string value); void add_header(std::string name, std::string value);
void add_header(std::string name, std::string value, int16_t token); void add_header(std::string name, std::string value, int16_t token);

View File

@ -243,7 +243,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
for (auto &lf : lfv) { for (auto &lf : lfv) {
switch (lf.type) { switch (lf.type) {
case SHRPX_LOGF_LITERAL: case SHRPX_LOGF_LITERAL:
std::tie(p, avail) = copy(lf.value.get(), avail, p); std::tie(p, avail) = copy(lf.value, avail, p);
break; break;
case SHRPX_LOGF_REMOTE_ADDR: case SHRPX_LOGF_REMOTE_ADDR:
std::tie(p, avail) = copy(lgsp.remote_addr, avail, p); std::tie(p, avail) = copy(lgsp.remote_addr, avail, p);
@ -273,7 +273,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
break; break;
case SHRPX_LOGF_HTTP: case SHRPX_LOGF_HTTP:
if (req) { if (req) {
auto hd = req->fs.header(lf.value.get()); auto hd = req->fs.header(lf.value);
if (hd) { if (hd) {
std::tie(p, avail) = copy((*hd).value, avail, p); std::tie(p, avail) = copy((*hd).value, avail, p);
break; break;

View File

@ -134,10 +134,10 @@ enum LogFragmentType {
}; };
struct LogFragment { struct LogFragment {
LogFragment(LogFragmentType type, std::unique_ptr<char[]> value = nullptr) LogFragment(LogFragmentType type, ImmutableString value = ImmutableString())
: type(type), value(std::move(value)) {} : type(type), value(std::move(value)) {}
LogFragmentType type; LogFragmentType type;
std::unique_ptr<char[]> value; ImmutableString value;
}; };
struct LogSpec { struct LogSpec {

View File

@ -218,6 +218,16 @@ inline std::unique_ptr<char[]> strcopy(const std::unique_ptr<char[]> &val,
// appear before the final terminal NULL. // appear before the final terminal NULL.
class ImmutableString { class ImmutableString {
public: public:
using traits_type = std::char_traits<char>;
using value_type = traits_type::char_type;
using allocator_type = std::allocator<char>;
using size_type = std::allocator_traits<allocator_type>::size_type;
using difference_type =
std::allocator_traits<allocator_type>::difference_type;
using const_reference = const value_type &;
using const_pointer = const value_type *;
using const_iterator = const_pointer;
ImmutableString() : len(0) {} ImmutableString() : len(0) {}
ImmutableString(const char *s, size_t slen) ImmutableString(const char *s, size_t slen)
: len(slen), base(strcopy(s, len)) {} : len(slen), base(strcopy(s, len)) {}
@ -244,10 +254,10 @@ public:
} }
const char *c_str() const { return base.get(); } const char *c_str() const { return base.get(); }
size_t size() const { return len; } size_type size() const { return len; }
private: private:
size_t len; size_type len;
std::unique_ptr<char[]> base; std::unique_ptr<char[]> base;
}; };
@ -258,10 +268,19 @@ private:
// function can be used to export the content as std::string. // function can be used to export the content as std::string.
class StringRef { class StringRef {
public: public:
using traits_type = std::char_traits<char>;
using value_type = traits_type::char_type;
using allocator_type = std::allocator<char>;
using size_type = std::allocator_traits<allocator_type>::size_type;
using difference_type =
std::allocator_traits<allocator_type>::difference_type;
using const_reference = const value_type &;
using const_pointer = const value_type *;
using const_iterator = const_pointer;
StringRef() : base(""), len(0) {} StringRef() : base(""), len(0) {}
template <typename T> StringRef(const std::string &s) : base(s.c_str()), len(s.size()) {}
StringRef(const T &s) StringRef(const ImmutableString &s) : base(s.c_str()), len(s.size()) {}
: base(s.c_str()), len(s.size()) {}
StringRef(const char *s) : base(s), len(strlen(s)) {} StringRef(const char *s) : base(s), len(strlen(s)) {}
StringRef(const char *s, size_t n) : base(s), len(n) {} StringRef(const char *s, size_t n) : base(s), len(n) {}
@ -269,16 +288,31 @@ public:
return StringRef(s, N - 1); return StringRef(s, N - 1);
} }
const_iterator begin() const { return base; };
const_iterator cbegin() const { return base; };
const_iterator end() const { return base + len; };
const_iterator cend() const { return base + len; };
const char *c_str() const { return base; } const char *c_str() const { return base; }
size_t size() const { return len; } size_type size() const { return len; }
std::string str() const { return std::string(base, len); } std::string str() const { return std::string(base, len); }
private: private:
const char *base; const char *base;
size_t len; size_type len;
}; };
inline bool operator==(const StringRef &lhs, const std::string &rhs) {
return lhs.size() == rhs.size() &&
std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
}
inline bool operator==(const std::string &lhs, const StringRef &rhs) {
return rhs == lhs;
}
inline int run_app(std::function<int(int, char **)> app, int argc, inline int run_app(std::function<int(int, char **)> app, int argc,
char **argv) { char **argv) {
try { try {