12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2012 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#ifndef SHRPX_LOG_H 262c593315Sopenharmony_ci#define SHRPX_LOG_H 272c593315Sopenharmony_ci 282c593315Sopenharmony_ci#include "shrpx.h" 292c593315Sopenharmony_ci 302c593315Sopenharmony_ci#include <sys/types.h> 312c593315Sopenharmony_ci 322c593315Sopenharmony_ci#include <memory> 332c593315Sopenharmony_ci#include <vector> 342c593315Sopenharmony_ci#include <chrono> 352c593315Sopenharmony_ci 362c593315Sopenharmony_ci#include "shrpx_config.h" 372c593315Sopenharmony_ci#include "shrpx_log_config.h" 382c593315Sopenharmony_ci#include "tls.h" 392c593315Sopenharmony_ci#include "template.h" 402c593315Sopenharmony_ci#include "util.h" 412c593315Sopenharmony_ci 422c593315Sopenharmony_ciusing namespace nghttp2; 432c593315Sopenharmony_ci 442c593315Sopenharmony_ci#define ENABLE_LOG 1 452c593315Sopenharmony_ci 462c593315Sopenharmony_ci#define LOG_ENABLED(SEVERITY) (ENABLE_LOG && shrpx::Log::log_enabled(SEVERITY)) 472c593315Sopenharmony_ci 482c593315Sopenharmony_ci#define LOG(SEVERITY) shrpx::Log(SEVERITY, __FILE__, __LINE__) 492c593315Sopenharmony_ci 502c593315Sopenharmony_ci// Listener log 512c593315Sopenharmony_ci#define LLOG(SEVERITY, LISTEN) \ 522c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[LISTEN:" << LISTEN << "] ") 532c593315Sopenharmony_ci 542c593315Sopenharmony_ci// Worker log 552c593315Sopenharmony_ci#define WLOG(SEVERITY, WORKER) \ 562c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[WORKER:" << WORKER << "] ") 572c593315Sopenharmony_ci 582c593315Sopenharmony_ci// ClientHandler log 592c593315Sopenharmony_ci#define CLOG(SEVERITY, CLIENT_HANDLER) \ 602c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) \ 612c593315Sopenharmony_ci << "[CLIENT_HANDLER:" << CLIENT_HANDLER << "] ") 622c593315Sopenharmony_ci 632c593315Sopenharmony_ci// Upstream log 642c593315Sopenharmony_ci#define ULOG(SEVERITY, UPSTREAM) \ 652c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[UPSTREAM:" << UPSTREAM \ 662c593315Sopenharmony_ci << "]" \ 672c593315Sopenharmony_ci " ") 682c593315Sopenharmony_ci 692c593315Sopenharmony_ci// Downstream log 702c593315Sopenharmony_ci#define DLOG(SEVERITY, DOWNSTREAM) \ 712c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) \ 722c593315Sopenharmony_ci << "[DOWNSTREAM:" << DOWNSTREAM << "] ") 732c593315Sopenharmony_ci 742c593315Sopenharmony_ci// Downstream connection log 752c593315Sopenharmony_ci#define DCLOG(SEVERITY, DCONN) \ 762c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[DCONN:" << DCONN << "] ") 772c593315Sopenharmony_ci 782c593315Sopenharmony_ci// Downstream HTTP2 session log 792c593315Sopenharmony_ci#define SSLOG(SEVERITY, HTTP2) \ 802c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[DHTTP2:" << HTTP2 << "] ") 812c593315Sopenharmony_ci 822c593315Sopenharmony_ci// Memcached connection log 832c593315Sopenharmony_ci#define MCLOG(SEVERITY, MCONN) \ 842c593315Sopenharmony_ci (shrpx::Log(SEVERITY, __FILE__, __LINE__) << "[MCONN:" << MCONN << "] ") 852c593315Sopenharmony_ci 862c593315Sopenharmony_cinamespace shrpx { 872c593315Sopenharmony_ci 882c593315Sopenharmony_ciclass Downstream; 892c593315Sopenharmony_cistruct DownstreamAddr; 902c593315Sopenharmony_ci 912c593315Sopenharmony_cienum SeverityLevel { INFO, NOTICE, WARN, ERROR, FATAL }; 922c593315Sopenharmony_ci 932c593315Sopenharmony_ciusing LogBuffer = std::array<uint8_t, 4_k>; 942c593315Sopenharmony_ci 952c593315Sopenharmony_ciclass Log { 962c593315Sopenharmony_cipublic: 972c593315Sopenharmony_ci Log(int severity, const char *filename, int linenum); 982c593315Sopenharmony_ci ~Log(); 992c593315Sopenharmony_ci Log &operator<<(const std::string &s); 1002c593315Sopenharmony_ci Log &operator<<(const char *s); 1012c593315Sopenharmony_ci Log &operator<<(const StringRef &s); 1022c593315Sopenharmony_ci Log &operator<<(const ImmutableString &s); 1032c593315Sopenharmony_ci Log &operator<<(short n) { return *this << static_cast<long long>(n); } 1042c593315Sopenharmony_ci Log &operator<<(int n) { return *this << static_cast<long long>(n); } 1052c593315Sopenharmony_ci Log &operator<<(long n) { return *this << static_cast<long long>(n); } 1062c593315Sopenharmony_ci Log &operator<<(long long n); 1072c593315Sopenharmony_ci Log &operator<<(unsigned short n) { 1082c593315Sopenharmony_ci return *this << static_cast<unsigned long long>(n); 1092c593315Sopenharmony_ci } 1102c593315Sopenharmony_ci Log &operator<<(unsigned int n) { 1112c593315Sopenharmony_ci return *this << static_cast<unsigned long long>(n); 1122c593315Sopenharmony_ci } 1132c593315Sopenharmony_ci Log &operator<<(unsigned long n) { 1142c593315Sopenharmony_ci return *this << static_cast<unsigned long long>(n); 1152c593315Sopenharmony_ci } 1162c593315Sopenharmony_ci Log &operator<<(unsigned long long n); 1172c593315Sopenharmony_ci Log &operator<<(float n) { return *this << static_cast<double>(n); } 1182c593315Sopenharmony_ci Log &operator<<(double n); 1192c593315Sopenharmony_ci Log &operator<<(long double n); 1202c593315Sopenharmony_ci Log &operator<<(bool n); 1212c593315Sopenharmony_ci Log &operator<<(const void *p); 1222c593315Sopenharmony_ci template <typename T> Log &operator<<(const std::shared_ptr<T> &ptr) { 1232c593315Sopenharmony_ci return *this << ptr.get(); 1242c593315Sopenharmony_ci } 1252c593315Sopenharmony_ci Log &operator<<(void (*func)(Log &log)) { 1262c593315Sopenharmony_ci func(*this); 1272c593315Sopenharmony_ci return *this; 1282c593315Sopenharmony_ci } 1292c593315Sopenharmony_ci template <typename InputIt> void write_seq(InputIt first, InputIt last) { 1302c593315Sopenharmony_ci if (full_) { 1312c593315Sopenharmony_ci return; 1322c593315Sopenharmony_ci } 1332c593315Sopenharmony_ci 1342c593315Sopenharmony_ci auto d = std::distance(first, last); 1352c593315Sopenharmony_ci auto n = std::min(wleft(), static_cast<size_t>(d)); 1362c593315Sopenharmony_ci last_ = std::copy(first, first + n, last_); 1372c593315Sopenharmony_ci update_full(); 1382c593315Sopenharmony_ci } 1392c593315Sopenharmony_ci 1402c593315Sopenharmony_ci template <typename T> void write_hex(T n) { 1412c593315Sopenharmony_ci if (full_) { 1422c593315Sopenharmony_ci return; 1432c593315Sopenharmony_ci } 1442c593315Sopenharmony_ci 1452c593315Sopenharmony_ci if (n == 0) { 1462c593315Sopenharmony_ci if (wleft() < 4 /* for "0x00" */) { 1472c593315Sopenharmony_ci full_ = true; 1482c593315Sopenharmony_ci return; 1492c593315Sopenharmony_ci } 1502c593315Sopenharmony_ci *last_++ = '0'; 1512c593315Sopenharmony_ci *last_++ = 'x'; 1522c593315Sopenharmony_ci *last_++ = '0'; 1532c593315Sopenharmony_ci *last_++ = '0'; 1542c593315Sopenharmony_ci update_full(); 1552c593315Sopenharmony_ci return; 1562c593315Sopenharmony_ci } 1572c593315Sopenharmony_ci 1582c593315Sopenharmony_ci size_t nlen = 0; 1592c593315Sopenharmony_ci for (auto t = n; t; t >>= 8, ++nlen) 1602c593315Sopenharmony_ci ; 1612c593315Sopenharmony_ci 1622c593315Sopenharmony_ci nlen *= 2; 1632c593315Sopenharmony_ci 1642c593315Sopenharmony_ci if (wleft() < 2 /* for "0x" */ + nlen) { 1652c593315Sopenharmony_ci full_ = true; 1662c593315Sopenharmony_ci return; 1672c593315Sopenharmony_ci } 1682c593315Sopenharmony_ci 1692c593315Sopenharmony_ci *last_++ = '0'; 1702c593315Sopenharmony_ci *last_++ = 'x'; 1712c593315Sopenharmony_ci 1722c593315Sopenharmony_ci last_ += nlen; 1732c593315Sopenharmony_ci update_full(); 1742c593315Sopenharmony_ci 1752c593315Sopenharmony_ci auto p = last_ - 1; 1762c593315Sopenharmony_ci for (; n; n >>= 8) { 1772c593315Sopenharmony_ci uint8_t b = n & 0xff; 1782c593315Sopenharmony_ci *p-- = util::LOWER_XDIGITS[b & 0xf]; 1792c593315Sopenharmony_ci *p-- = util::LOWER_XDIGITS[b >> 4]; 1802c593315Sopenharmony_ci } 1812c593315Sopenharmony_ci } 1822c593315Sopenharmony_ci static void set_severity_level(int severity); 1832c593315Sopenharmony_ci // Returns the severity level by |name|. Returns -1 if |name| is 1842c593315Sopenharmony_ci // unknown. 1852c593315Sopenharmony_ci static int get_severity_level_by_name(const StringRef &name); 1862c593315Sopenharmony_ci static bool log_enabled(int severity) { return severity >= severity_thres_; } 1872c593315Sopenharmony_ci 1882c593315Sopenharmony_ci enum { 1892c593315Sopenharmony_ci fmt_dec = 0x00, 1902c593315Sopenharmony_ci fmt_hex = 0x01, 1912c593315Sopenharmony_ci }; 1922c593315Sopenharmony_ci 1932c593315Sopenharmony_ci void set_flags(int flags) { flags_ = flags; } 1942c593315Sopenharmony_ci 1952c593315Sopenharmony_ciprivate: 1962c593315Sopenharmony_ci size_t rleft() { return last_ - begin_; } 1972c593315Sopenharmony_ci size_t wleft() { return end_ - last_; } 1982c593315Sopenharmony_ci void update_full() { full_ = last_ == end_; } 1992c593315Sopenharmony_ci 2002c593315Sopenharmony_ci LogBuffer &buf_; 2012c593315Sopenharmony_ci uint8_t *begin_; 2022c593315Sopenharmony_ci uint8_t *end_; 2032c593315Sopenharmony_ci uint8_t *last_; 2042c593315Sopenharmony_ci const char *filename_; 2052c593315Sopenharmony_ci uint32_t flags_; 2062c593315Sopenharmony_ci int severity_; 2072c593315Sopenharmony_ci int linenum_; 2082c593315Sopenharmony_ci bool full_; 2092c593315Sopenharmony_ci static int severity_thres_; 2102c593315Sopenharmony_ci}; 2112c593315Sopenharmony_ci 2122c593315Sopenharmony_cinamespace log { 2132c593315Sopenharmony_civoid hex(Log &log); 2142c593315Sopenharmony_civoid dec(Log &log); 2152c593315Sopenharmony_ci} // namespace log 2162c593315Sopenharmony_ci 2172c593315Sopenharmony_ci#define TTY_HTTP_HD (log_config()->errorlog_tty ? "\033[1;34m" : "") 2182c593315Sopenharmony_ci#define TTY_RST (log_config()->errorlog_tty ? "\033[0m" : "") 2192c593315Sopenharmony_ci 2202c593315Sopenharmony_cienum class LogFragmentType { 2212c593315Sopenharmony_ci NONE, 2222c593315Sopenharmony_ci LITERAL, 2232c593315Sopenharmony_ci REMOTE_ADDR, 2242c593315Sopenharmony_ci TIME_LOCAL, 2252c593315Sopenharmony_ci TIME_ISO8601, 2262c593315Sopenharmony_ci REQUEST, 2272c593315Sopenharmony_ci STATUS, 2282c593315Sopenharmony_ci BODY_BYTES_SENT, 2292c593315Sopenharmony_ci HTTP, 2302c593315Sopenharmony_ci AUTHORITY, 2312c593315Sopenharmony_ci REMOTE_PORT, 2322c593315Sopenharmony_ci SERVER_PORT, 2332c593315Sopenharmony_ci REQUEST_TIME, 2342c593315Sopenharmony_ci PID, 2352c593315Sopenharmony_ci ALPN, 2362c593315Sopenharmony_ci TLS_CIPHER, 2372c593315Sopenharmony_ci SSL_CIPHER = TLS_CIPHER, 2382c593315Sopenharmony_ci TLS_PROTOCOL, 2392c593315Sopenharmony_ci SSL_PROTOCOL = TLS_PROTOCOL, 2402c593315Sopenharmony_ci TLS_SESSION_ID, 2412c593315Sopenharmony_ci SSL_SESSION_ID = TLS_SESSION_ID, 2422c593315Sopenharmony_ci TLS_SESSION_REUSED, 2432c593315Sopenharmony_ci SSL_SESSION_REUSED = TLS_SESSION_REUSED, 2442c593315Sopenharmony_ci TLS_SNI, 2452c593315Sopenharmony_ci TLS_CLIENT_FINGERPRINT_SHA1, 2462c593315Sopenharmony_ci TLS_CLIENT_FINGERPRINT_SHA256, 2472c593315Sopenharmony_ci TLS_CLIENT_ISSUER_NAME, 2482c593315Sopenharmony_ci TLS_CLIENT_SERIAL, 2492c593315Sopenharmony_ci TLS_CLIENT_SUBJECT_NAME, 2502c593315Sopenharmony_ci BACKEND_HOST, 2512c593315Sopenharmony_ci BACKEND_PORT, 2522c593315Sopenharmony_ci METHOD, 2532c593315Sopenharmony_ci PATH, 2542c593315Sopenharmony_ci PATH_WITHOUT_QUERY, 2552c593315Sopenharmony_ci PROTOCOL_VERSION, 2562c593315Sopenharmony_ci}; 2572c593315Sopenharmony_ci 2582c593315Sopenharmony_cistruct LogFragment { 2592c593315Sopenharmony_ci LogFragment(LogFragmentType type, StringRef value = StringRef::from_lit("")) 2602c593315Sopenharmony_ci : type(type), value(std::move(value)) {} 2612c593315Sopenharmony_ci LogFragmentType type; 2622c593315Sopenharmony_ci StringRef value; 2632c593315Sopenharmony_ci}; 2642c593315Sopenharmony_ci 2652c593315Sopenharmony_cistruct LogSpec { 2662c593315Sopenharmony_ci Downstream *downstream; 2672c593315Sopenharmony_ci StringRef remote_addr; 2682c593315Sopenharmony_ci StringRef alpn; 2692c593315Sopenharmony_ci StringRef sni; 2702c593315Sopenharmony_ci SSL *ssl; 2712c593315Sopenharmony_ci std::chrono::high_resolution_clock::time_point request_end_time; 2722c593315Sopenharmony_ci StringRef remote_port; 2732c593315Sopenharmony_ci uint16_t server_port; 2742c593315Sopenharmony_ci pid_t pid; 2752c593315Sopenharmony_ci}; 2762c593315Sopenharmony_ci 2772c593315Sopenharmony_civoid upstream_accesslog(const std::vector<LogFragment> &lf, 2782c593315Sopenharmony_ci const LogSpec &lgsp); 2792c593315Sopenharmony_ci 2802c593315Sopenharmony_ciint reopen_log_files(const LoggingConfig &loggingconf); 2812c593315Sopenharmony_ci 2822c593315Sopenharmony_ci// Logs message when process whose pid is |pid| and exist status is 2832c593315Sopenharmony_ci// |rstatus| exited. The |msg| is prepended to the log message. 2842c593315Sopenharmony_civoid log_chld(pid_t pid, int rstatus, const char *msg); 2852c593315Sopenharmony_ci 2862c593315Sopenharmony_civoid redirect_stderr_to_errorlog(const LoggingConfig &loggingconf); 2872c593315Sopenharmony_ci 2882c593315Sopenharmony_ci// Makes internal copy of stderr (and possibly stdout in the future), 2892c593315Sopenharmony_ci// which is then used as pointer to /dev/stderr or /proc/self/fd/2 2902c593315Sopenharmony_civoid store_original_fds(); 2912c593315Sopenharmony_ci 2922c593315Sopenharmony_ci// Restores the original stderr that was stored with copy_original_fds 2932c593315Sopenharmony_ci// Used just before execv 2942c593315Sopenharmony_civoid restore_original_fds(); 2952c593315Sopenharmony_ci 2962c593315Sopenharmony_ci// Closes |fd| which was returned by open_log_file (see below) 2972c593315Sopenharmony_ci// and sets it to -1. In the case that |fd| points to stdout or 2982c593315Sopenharmony_ci// stderr, or is -1, the descriptor is not closed (but still set to -1). 2992c593315Sopenharmony_civoid close_log_file(int &fd); 3002c593315Sopenharmony_ci 3012c593315Sopenharmony_ci// Opens |path| with O_APPEND enabled. If file does not exist, it is 3022c593315Sopenharmony_ci// created first. This function returns file descriptor referring the 3032c593315Sopenharmony_ci// opened file if it succeeds, or -1. 3042c593315Sopenharmony_ciint open_log_file(const char *path); 3052c593315Sopenharmony_ci 3062c593315Sopenharmony_ci} // namespace shrpx 3072c593315Sopenharmony_ci 3082c593315Sopenharmony_ci#endif // SHRPX_LOG_H 309