2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_LOG_WRITER_H_
17 #define incl_HPHP_LOG_WRITER_H_
21 #include <folly/Conv.h>
22 #include <folly/Format.h>
24 #include "hphp/runtime/base/timestamp.h"
25 #include "hphp/runtime/server/access-log.h"
26 #include "hphp/runtime/server/http-server.h"
27 #include "hphp/runtime/server/request-uri.h"
28 #include "hphp/runtime/server/server-note.h"
29 #include "hphp/runtime/server/server-stats.h"
30 #include "hphp/runtime/server/server.h"
31 #include "hphp/runtime/server/transport.h"
32 #include "hphp/runtime/server/virtual-host.h"
33 #include "hphp/util/hardware-counter.h"
34 #include "hphp/util/timer.h"
35 #include "hphp/util/service-data.h"
38 ///////////////////////////////////////////////////////////////////////////////
40 struct ClassicWriter final
: LogWriter
{
41 ClassicWriter(const AccessLogFileData
& alfd
, LogChannel chan
)
45 ~ClassicWriter() override
;
46 void init(const std::string
& username
,
47 AccessLog::GetThreadDataFunc fn
) override
;
48 void write(Transport
* transport
, const VirtualHost
* vhost
) override
;
49 const static std::string handle
;
51 const AccessLogFileData m_logdata
;
52 static bool parseConditions(const char*& fmt
, int code
);
53 static std::string
parseArgument(const char*& fmt
);
54 static void skipField(const char*& fmt
);
57 struct FieldGenerator
{
58 FieldGenerator(Transport
* t
, const VirtualHost
* vh
,
59 AccessLog::ThreadData
* tdata
)
65 bool gen(char field
, const std::string
& arg
, T
& out
);
67 static std::string
escapeData(const char* s
, int len
);
69 const VirtualHost
* vhost
;
70 AccessLog::ThreadData
* threadData
;
74 bool FieldGenerator::gen(char field
, const std::string
& arg
, T
& out
) {
75 int responseSize
= transport
->getResponseSize();
76 int code
= transport
->getResponseCode();
80 if (responseSize
== 0) return false;
83 out
= folly::to
<T
>(responseSize
);
87 if (arg
.empty()) return false;
88 std::string config
= IniSetting::Get(arg
);
89 if (config
.empty()) return false;
90 out
= folly::to
<T
>(config
);
95 if (arg
.empty()) return false;
96 std::string cookie
= transport
->getCookie(arg
);
97 if (cookie
.empty()) return false;
98 out
= folly::to
<T
>(escapeData(cookie
.c_str(), cookie
.size()));
104 Timer::GetMonotonicTime(now
);
105 out
= folly::to
<T
>(gettime_diff_us(transport
->getWallTime(), now
));
110 #ifdef CLOCK_THREAD_CPUTIME_ID
112 gettime(CLOCK_THREAD_CPUTIME_ID
, &now
);
113 out
= folly::to
<T
>(gettime_diff_us(transport
->getCpuTime(), now
));
121 std::string host
= transport
->getRemoteHost();
122 if (host
.empty()) host
= transport
->getRemoteAddr();
123 out
= folly::to
<T
>(host
);
127 if (arg
.empty()) return false;
128 out
= folly::to
<T
>(ServerStats::Get(arg
));
132 if (arg
.empty()) return false;
133 std::string header
= transport
->getHeader(arg
.c_str());
134 if (header
.empty()) return false;
135 if (vhost
&& vhost
->hasLogFilter() &&
136 strcasecmp(arg
.c_str(), "Referer") == 0) {
137 out
= folly::to
<T
>(vhost
->filterUrl(header
));
139 out
= folly::to
<T
>(header
);
144 out
= folly::to
<T
>(transport
->getRequestSize());
148 auto static jitMaturityCounter
=
149 ServiceData::createCounter("jit.maturity");
150 if (jitMaturityCounter
) {
151 out
= folly::to
<T
>(jitMaturityCounter
->getValue());
156 if (arg
.empty()) return false;
158 String note
= ServerNote::Get(arg
);
159 if (note
.isNull()) return false;
160 out
= folly::to
<T
>(note
.data());
164 out
= folly::to
<T
>(ServerStats::Get("request.memory_exceeded.non_psp"));
167 out
= folly::to
<T
>(ServerStats::Get("request.memory_exceeded.psp"));
170 out
= folly::to
<T
>(ServerStats::Get("request.timed_out.non_psp"));
173 out
= folly::to
<T
>(ServerStats::Get("request.timed_out.psp"));
177 const char *method
= transport
->getMethodName();
178 if (!method
|| !method
[0]) return false;
179 const char *url
= transport
->getUrl();
180 out
= folly::to
<T
>(folly::sformat(
181 "{} {} HTTP/{}", method
,
182 (vhost
&& vhost
->hasLogFilter()) ? vhost
->filterUrl(url
) : url
,
183 transport
->getHTTPVersion()
188 out
= folly::to
<T
>(code
);
191 // %S is not defined in Apache, we grab it here
193 const std::string
& info(transport
->getResponseInfo());
194 if (info
.empty()) return false;
195 out
= folly::to
<T
>(info
);
200 const char *fmt
= arg
.empty() ? "[%d/%b/%Y:%H:%M:%S %z]" : arg
.c_str();
205 localtime_r(&rawtime
, &timeinfo
);
206 strftime(buf
, 256, fmt
, &timeinfo
);
207 out
= folly::to
<T
>(buf
);
211 out
= folly::to
<T
>(threadData
?
212 TimeStamp::Current() - threadData
->startTime
: 0);
217 RequestURI::splitURL(transport
->getUrl(), b
, q
);
218 out
= folly::to
<T
>(b
.c_str());
223 out
= folly::to
<T
>(TimeStamp::Current() - HttpServer::StartTime
);
227 std::string host
= transport
->getHeader("Host");
228 const std::string
&sname
= VirtualHost::GetCurrent()->serverName(host
);
229 if (sname
.empty() || RuntimeOption::ForceServerNameToHeader
) {
230 out
= folly::to
<T
>(host
);
232 out
= folly::to
<T
>(sname
);
238 int64_t now
= HardwareCounter::GetInstructionCount();
239 out
= folly::to
<T
>(now
- transport
->getInstructions());
243 out
= folly::to
<T
>(ServerStats::Get("page.inst.psp"));
246 out
= folly::to
<T
>(ServerStats::Get("page.wall.psp"));
249 out
= folly::to
<T
>(ServerStats::Get("page.cpu.psp"));
257 ///////////////////////////////////////////////////////////////////////////////
260 #endif // incl_HPHP_LOG_WRITER_H_