This is my 18th day of the August Genwen Challenge
This series code address: github.com/HashZhang/s…
Server: undertow: # accesslog accesslog: # Log dir:./log True # format, with various placeholders specifying pattern: '{ "transportProtocol":"%{TRANSPORT_PROTOCOL}", "scheme":"%{SCHEME}", "protocol":"%{PROTOCOL}", "method":"%{METHOD}", "reqHeaderUserAgent":"%{i,User-Agent}", "cookieUserId": "%{c,userId}", "queryTest": "%{q,test}", "queryString": "%q", "relativePath": "%R, %{REQUEST_PATH}, %{RESOLVED_PATH}", "requestLine": "%r", "uri": "%U", "thread": "%I", "hostPort": "%{HOST_AND_PORT}", "localIp": "%A", "localPort": "%p", "localServerName": "%v", "remoteIp": "%a", "remoteHost": "%h", "bytesSent": "%b", "time":"%{time,yyyy-MM-dd HH:mm:ss.S}", "status":"%s", "reason":"%{RESPONSE_REASON_PHRASE}", "respHeaderUserSession":"%{o,userSession}", "respCookieUserId":"%{resp-cookie,userId}", "timeUsed":"%Dms, %Ts, %{RESPONSE_TIME}ms, %{RESPONSE_TIME_MICROS} us, %{RESPONSE_TIME_NANOS} ns",}' # access_log prefix: Log. # File suffix, default log suffix: log # Whether to create log files to write access logs, the default is true # Currently, only the date can be rotated, one log file a day rotate: trueCopy the code
Undertow accesslog processing core class abstraction is IO Undertow. Server. Handlers. The accesslog. AccesslogReceiver. There is only one because the Undertow AccesslogReceiver implementation in use, namely IO. Undertow. Server. Handlers. Accesslog. DefaultAccessLogReceiver.
View the rotate of DefaultAccessLogReceiver:
DefaultAccessLogReceiver
/** * Compute rotate time point */ private void calculateChangeOverPoint() {Calendar = calendar.getInstance (); /** * compute rotate time point */ private void calculateChangeOverPoint() {Calendar = calendar.getinstance (); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); Calendar.add (calendar.date, 1); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US); currentDateString = df.format(new Date()); // if there is an existing default log file, use the date last modified instead of the current date if (Files.exists(defaultLogFile)) { try { currentDateString = df.format(new Date(Files.getLastModifiedTime(defaultLogFile).toMillis())); } catch(IOException e){// ignore. use the current date if exception happens.} // Rotate time is 0 on the next day changeOverPoint = calendar.getTimeInMillis(); }Copy the code
The accesslog placeholder in Undertow is a property abstracted from the HTTP Server Exchange after the Undertow Listener resolves the request.
The table in the official documentation is not exhaustive, and note that it does not specify, for example, that certain placeholders must have Undertow features on in order to use them. So let’s list it here.
First of all, the argument placeholders, such as %{I, the value of the header you want to look at} look at one of the key values of the header. Make sure there is no space after the comma, because this space will count into the key and not get the key you want.
Request related attributes
describe | Abbreviation placeholder | Full name placeholder | Parameter placeholder | The source code |
---|---|---|---|---|
Request transport protocol, equivalent toRequest protocol | There is no | %{TRANSPORT_PROTOCOL} |
There is no | TransportProtocolAttribute |
Request mode, such as HTTP or HTTPS | %{SCHEME} |
There is no | RequestSchemeAttribute |
|
Request protocol, for exampleHTTP / 1.1 等 |
%H |
%{PROTOCOL} |
There is no | RequestProtocolAttribute |
Request methods such as GET, POST, and so on | %m |
%{METHOD} |
There is no | RequestMethodAttribute |
Request a value of the Header | There is no | There is no | %{I, you want to see the header value} |
RequestHeaderAttribute |
Some value of the Cookie | There is no | There is no | %{c, you want to see the cookie value} or%{req-cookie, you want to see the cookie value} |
correspondingCookieAttribute 和 RequestCookieAttribute |
The path parameter PathVariable is not processed by Undertow’s Listener or Handler, so it cannot be intercepted and cannot be confirmed whether it is a PathVariable or a URL path. So,Placeholders for PathVariable will not work. | There is no | There is no | %{p, you want to view the path parameter key} |
PathParameterAttribute |
The request parameter, that is, the url’s? And then key-value pairs, where you can choose to look at the value of a particular key. | There is no | There is no | %{q, the request key you want to view} |
QueryParameterAttribute |
The request parameter string, which is the url’s? All subsequent characters} | %q (Not included?) |
%{QUERY_STRING} (Not included?) ;%{BARE_QUERY_STRING} (contain? |
There is no | QueryStringAttribute |
Request RelativePath (in Spring Boot, RequestPath is equivalent to RelativePath and ResolvedPath in most cases), which excludes the host, port, and request parameter strings | %R |
%{RELATIVE_PATH} or%{REQUEST_PATH} or%{RESOLVED_PATH} |
There is no | correspondingRelativePathAttribute 和 RequestPathAttribute 和 ResolvedPathAttribute |
Request overall string, including request method, request relative path, request parameter string, request protocol, for exampleGet /test? A = b HTTP / 1.1 |
%r |
%{REQUEST_LINE} |
There is no | RequestLineAttribute |
Request URI, including request relative path, request parameter string | %U |
%{REQUEST_URL} |
There is no | RequestURLAttribute |
The thread that processes the request | %I |
%{THREAD_NAME} |
There is no | ThreadNameAttribute |
Note:
- The path parameter PathVariable is not processed by Undertow’s Listener or Handler, so it cannot be intercepted and cannot be confirmed whether it is a PathVariable or a URL path. Therefore, placeholders for PathVariable will not work.
Request address correlation
describe | Abbreviation placeholder | Full name placeholder | Parameter placeholder | The source code |
---|---|---|---|---|
If host is null, the local address and port will be obtained. If no port is obtained, the default port will be used based on the protocol (HTTP :80, HTTPS :443). | There is no | %{HOST_AND_PORT} |
There is no | HostAndPortAttribute |
Request local address IP | %A |
%{LOCAL_IP} |
There is no | LocalIPAttribute |
Request the local Port Port | %p |
%{LOCAL_PORT} |
There is no | LocalPortAttribute |
Request the local Host name, usually the Host value in the HTTP request Header, or if Host is empty, get the local address | %v |
%{LOCAL_SERVER_NAME} |
There is no | LocalServerNameAttribute |
Request the remote host name and get the remote host address through the connection | %h |
%{REMOTE_HOST} |
There is no | RemoteHostAttribute |
Request a remote IP address and obtain the remote IP address through the connection | %a |
%{REMOTE_IP} |
There is no | RemoteIPAttribute |
Note:
- The requested remote address is not usually obtained from the request connection, but from the Http Header
X-forwarded-for
orX-real-ip
And so on, because now requests are sent through various VPNS, load balancers.
Response-dependent attributes
describe | Abbreviation placeholder | Full name placeholder | Parameter placeholder | The source code |
---|---|---|---|---|
Size of bytes sent, except Http headers | %b (if it is empty it is -) or%B (0 if null) |
%{BYTES_SENT} (0 if null) |
There is no | BytesSentAttribute |
Accesslog time, which is not the time to receive the request, but the time to respond | %t |
%{DATE_TIME} |
%{time, you customize the format of SimpleDateFormat in Java} |
DateTimeAttribute |
HTTP response status code | %s |
%{RESPONSE_CODE} |
There is no | ResponseCodeAttribute |
HTTP Response Causes | There is no | %{RESPONSE_REASON_PHRASE} |
There is no | ResponseReasonPhraseAttribute |
Respond to a value of the Header | There is no | There is no | %{o, you want to see the header value} |
ResponseHeaderAttribute |
Responds to a value of the Cookie | There is no | There is no | %{resp-cookie, you want to see the cookie value} |
ResponseCookieAttribute |
Response time,By default, undertow does not enable request-time statistics, which can be used to calculate response time | %D (ms, for example, 56 for 56ms)%T (seconds, for example 5.067 for 5.067 seconds) |
%{RESPONSE_TIME} (equivalent to the%D ) %{RESPONSE_TIME_MICROS} (in milliseconds)%{RESPONSE_TIME_NANOS} (ns) |
There is no | ResponseTimeAttribute |
Note: Undertow does not enable request time statistics by default. It needs to be enabled to calculate response time. How to enable it? By registering a WebServerFactoryCustomizer to Spring ApplicationContext. Look at the code below (project address: github.com/HashZhang/s…) :
spring.factories
(Omit irrelevant code)
# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.hashjang.spring.cloud.iiford.service.common.auto.UndertowAutoConfiguration
Copy the code
UndertowAutoConfiguration
// Set proxyBeanMethods=false, because no @bean methods call each other and return the same Bean every time, no proxy is necessary, Close to increase startup @ the Configuration (proxyBeanMethods = false) @ Import (WebServerConfiguration. Class) public class UndertowAutoConfiguration { }Copy the code
WebServerConfiguration
// Set proxyBeanMethods=false, because no @bean methods call each other and return the same Bean every time, no proxy is necessary, @configuration (proxyBeanMethods = false) public class WebServerConfiguration {@bean public WebServerFactoryCustomizer<ConfigurableUndertowWebServerFactory> undertowWebServerAccessLogTimingEnabler(ServerProperties serverProperties) { return new DefaultWebServerFactoryCustomizer(serverProperties); }}Copy the code
DefaultWebServerFactoryCustomizer
public class DefaultWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableUndertowWebServerFactory> { private final ServerProperties serverProperties; public DefaultWebServerFactoryCustomizer(ServerProperties serverProperties) { this.serverProperties = serverProperties; } @Override public void customize(ConfigurableUndertowWebServerFactory factory) { String pattern = serverProperties.getUndertow().getAccesslog().getPattern(); If the response time is printed in the accesslog configuration, Open a record request start time configure if (logRequestProcessingTiming (pattern)) {factory. AddBuilderCustomizers (builder - > builder.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, true)); } } private boolean logRequestProcessingTiming(String pattern) { if (StringUtils.isBlank(pattern)) { return false; } / / whether accesslog configuration view response time return pattern. The contains (ResponseTimeAttribute. RESPONSE_TIME_MICROS) | | pattern.contains(ResponseTimeAttribute.RESPONSE_TIME_MILLIS) || pattern.contains(ResponseTimeAttribute.RESPONSE_TIME_NANOS) || pattern.contains(ResponseTimeAttribute.RESPONSE_TIME_MILLIS_SHORT) || pattern.contains(ResponseTimeAttribute.RESPONSE_TIME_SECONDS_SHORT); }}Copy the code
other
There are also security-related attributes (SSL related, login Authentication related) that are not generally used for internal microservice calls, so we won’t go into them here. Other built-in properties, which are generally not used in a Spring Boot environment, will not be discussed here.
For example,
The example accessLog request we initially configured returns the following (JSON formatted) :
TransportProtocol: "HTTP/1.1", "Scheme ": "HTTP ", "protocol": "HTTP/1.1", "method": "GET", "reqHeaderUserAgent": PostmanRuntime/7.26.10", "cookieUserId": "testreQuestUserId ", "queryTest": "1", "queryString": "? test=1&query=2", "relativePath": "/test, /test, -", "requestLine": "GET /test? Test = 1 & query = 2 HTTP / 1.1 ", "uri" : "/ test", "thread" : "XNIO task - 2-1", "hostPort" : "127.0.0.1:8102", "localIp" : "127.0.0.1", "localPort" : "8102", "localServerName" : "127.0.0.1", "remoteIp" : "127.0.0.1", "remoteHost" : "127.0.0.1", "bytesSent" : "26", "time", "the 2021-04-08 00:07:50. 410", "status" : "200", "" reason" : "OK", "respHeaderUserSession": "testResponseHeaderUserSession", "respCookieUserId": "TestResponseCookieUserId ", "timeUsed": "3683ms, 3.683s, 3683ms, 3683149 us, 3683149200 ns",}Copy the code
In this section, we introduce how to configure Undertow’s Accesslog in detail. Various placeholders for accesslog are listed. Users can configure their desired accesslog information and format according to these information. In the next section, we’ll take a closer look at the custom code for Undertow in our framework
Wechat search “my programming meow” public account, a daily brush, easy to improve skills, won a variety of offers: