Skip to content

Commit a76a2c5

Browse files
author
Azeem Muzammil
committed
Implement AccessLog support for HTTP/2.0
1 parent c0c3cdf commit a76a2c5

File tree

15 files changed

+699
-17
lines changed

15 files changed

+699
-17
lines changed

ballerina/http_log_manager.bal

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ public type TraceLogAdvancedConfiguration record {|
3535
# Represents HTTP access log configuration.
3636
#
3737
# + console - Boolean value to enable or disable console access logs
38+
# + format - The format of access logs to be printed (either `flat` or `json`)
39+
# + attributes - The list of attributes of access logs to be printed
3840
# + path - Optional file path to store access logs
3941
public type AccessLogConfiguration record {|
4042
boolean console = false;
43+
string format = "flat";
44+
string[] attributes?;
4145
string path?;
4246
|};
4347

native/src/main/java/io/ballerina/stdlib/http/api/HttpConstants.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,32 @@ public final class HttpConstants {
323323
public static final String HTTP_TRACE_LOG_ENABLED = "http.tracelog.enabled";
324324
public static final String HTTP_ACCESS_LOG = "http.accesslog";
325325
public static final String HTTP_ACCESS_LOG_ENABLED = "http.accesslog.enabled";
326+
public static final String HTTP_LOG_FORMAT_JSON = "json";
326327

327328
// TraceLog and AccessLog configs
328329
public static final BString HTTP_LOG_CONSOLE = StringUtils.fromString("console");
330+
public static final BString HTTP_LOG_FORMAT = StringUtils.fromString("format");
331+
public static final BString HTTP_LOG_ATTRIBUTES = StringUtils.fromString("attributes");
329332
public static final BString HTTP_LOG_FILE_PATH = StringUtils.fromString("path");
330333
public static final BString HTTP_TRACE_LOG_HOST = StringUtils.fromString("host");
331334
public static final BString HTTP_TRACE_LOG_PORT = StringUtils.fromString("port");
332335
public static final BString HTTP_LOGGING_PROTOCOL = StringUtils.fromString("HTTP");
333336

337+
// AccessLog fiend names
338+
public static final String ATTRIBUTE_IP = "ip";
339+
public static final String ATTRIBUTE_DATE_TIME = "date_time";
340+
public static final String ATTRIBUTE_REQUEST_METHOD = "request_method";
341+
public static final String ATTRIBUTE_REQUEST_URI = "request_uri";
342+
public static final String ATTRIBUTE_SCHEME = "scheme";
343+
public static final String ATTRIBUTE_REQUEST = "request";
344+
public static final String ATTRIBUTE_STATUS = "status";
345+
public static final String ATTRIBUTE_REQUEST_BODY_SIZE = "request_body_size";
346+
public static final String ATTRIBUTE_RESPONSE_BODY_SIZE = "response_body_size";
347+
public static final String ATTRIBUTE_REQUEST_TIME = "request_time";
348+
public static final String ATTRIBUTE_HTTP_REFERRER = "http_referrer";
349+
public static final String ATTRIBUTE_HTTP_USER_AGENT = "http_user_agent";
350+
public static final String ATTRIBUTE_HTTP_X_FORWARDED_FOR = "http_x_forwarded_for";
351+
334352
// ResponseCacheControl struct field names
335353
public static final BString RES_CACHE_CONTROL_MUST_REVALIDATE_FIELD = StringUtils.fromString("mustRevalidate");
336354
public static final BString RES_CACHE_CONTROL_NO_CACHE_FIELD = StringUtils.fromString("noCache");

native/src/main/java/io/ballerina/stdlib/http/api/logging/HttpLogManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import io.ballerina.runtime.api.values.BMap;
2222
import io.ballerina.runtime.api.values.BString;
23+
import io.ballerina.stdlib.http.api.logging.accesslog.HttpAccessLogConfig;
2324
import io.ballerina.stdlib.http.api.logging.formatters.HttpAccessLogFormatter;
2425
import io.ballerina.stdlib.http.api.logging.formatters.HttpTraceLogFormatter;
2526
import io.ballerina.stdlib.http.api.logging.formatters.JsonLogFormatter;
@@ -70,6 +71,7 @@ public HttpLogManager(boolean traceLogConsole, BMap traceLogAdvancedConfig, BMap
7071
this.protocol = protocol.getValue();
7172
this.setHttpTraceLogHandler(traceLogConsole, traceLogAdvancedConfig);
7273
this.setHttpAccessLogHandler(accessLogConfig);
74+
HttpAccessLogConfig.getInstance().initializeHttpAccessLogConfig(accessLogConfig);
7375
}
7476

7577
/**
@@ -166,5 +168,4 @@ public void setHttpAccessLogHandler(BMap accessLogConfig) {
166168
stdErr.println("ballerina: " + protocol + " access log enabled");
167169
}
168170
}
169-
170171
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package io.ballerina.stdlib.http.api.logging.accesslog;
2+
3+
import io.ballerina.runtime.api.values.BArray;
4+
import io.ballerina.runtime.api.values.BMap;
5+
import io.ballerina.runtime.api.values.BString;
6+
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.HashSet;
10+
import java.util.List;
11+
import java.util.Set;
12+
import java.util.stream.Collectors;
13+
14+
import static io.ballerina.stdlib.http.api.HttpConstants.ATTRIBUTE_HTTP_REFERRER;
15+
import static io.ballerina.stdlib.http.api.HttpConstants.ATTRIBUTE_HTTP_USER_AGENT;
16+
import static io.ballerina.stdlib.http.api.HttpConstants.ATTRIBUTE_HTTP_X_FORWARDED_FOR;
17+
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_ATTRIBUTES;
18+
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_FORMAT;
19+
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_FORMAT_JSON;
20+
21+
public class HttpAccessLogConfig {
22+
23+
private static final HttpAccessLogConfig instance = new HttpAccessLogConfig();
24+
private static final Set<String> EXCLUDED_ATTRIBUTES = new HashSet<>(List.of(
25+
ATTRIBUTE_HTTP_REFERRER, ATTRIBUTE_HTTP_USER_AGENT, ATTRIBUTE_HTTP_X_FORWARDED_FOR
26+
));
27+
private BMap accessLogConfig;
28+
29+
private HttpAccessLogConfig() {}
30+
31+
public static HttpAccessLogConfig getInstance() {
32+
return instance;
33+
}
34+
35+
public void initializeHttpAccessLogConfig(BMap accessLogConfig) {
36+
this.accessLogConfig = accessLogConfig;
37+
}
38+
39+
public List<String> getCustomHeaders() {
40+
List<String> attributes = getAccessLogAttributes();
41+
if (attributes == null) {
42+
return Collections.emptyList();
43+
}
44+
45+
return attributes.stream()
46+
.filter(attr -> attr.startsWith("http_") && !EXCLUDED_ATTRIBUTES.contains(attr))
47+
.map(attr -> attr.substring(5))
48+
.collect(Collectors.toList());
49+
}
50+
51+
public HttpAccessLogFormat getAccessLogFormat() {
52+
if (accessLogConfig != null) {
53+
BString logFormat = accessLogConfig.getStringValue(HTTP_LOG_FORMAT);
54+
if (logFormat.getValue().equals(HTTP_LOG_FORMAT_JSON)) {
55+
return HttpAccessLogFormat.JSON;
56+
}
57+
}
58+
return HttpAccessLogFormat.FLAT;
59+
}
60+
61+
public List<String> getAccessLogAttributes() {
62+
if (accessLogConfig != null) {
63+
BArray logAttributes = accessLogConfig.getArrayValue(HTTP_LOG_ATTRIBUTES);
64+
if (logAttributes != null) {
65+
return Arrays.stream(logAttributes.getStringArray())
66+
.collect(Collectors.toList());
67+
}
68+
}
69+
return null;
70+
}
71+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
package io.ballerina.stdlib.http.api.logging.accesslog;
20+
21+
public enum HttpAccessLogFormat {
22+
FLAT, JSON
23+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
package io.ballerina.stdlib.http.api.logging.accesslog;
20+
21+
import java.util.Calendar;
22+
import java.util.HashMap;
23+
import java.util.Map;
24+
25+
public class HttpAccessLogMessage {
26+
private String ip;
27+
private Calendar dateTime;
28+
private String requestMethod;
29+
private String requestUri;
30+
private String scheme;
31+
private int status;
32+
private long requestBodySize;
33+
private long responseBodySize;
34+
private long requestTime;
35+
private String httpReferrer;
36+
private String httpUserAgent;
37+
private String httpXForwardedFor;
38+
private String host;
39+
private int port;
40+
private Map<String, String> customHeaders;
41+
42+
public HttpAccessLogMessage() {
43+
this.customHeaders = new HashMap<>();
44+
}
45+
46+
public HttpAccessLogMessage(String ip, Calendar dateTime, String requestMethod, String requestUri, String scheme,
47+
int status, long responseBodySize, String httpReferrer, String httpUserAgent) {
48+
this.ip = ip;
49+
this.dateTime = dateTime;
50+
this.requestMethod = requestMethod;
51+
this.requestUri = requestUri;
52+
this.scheme = scheme;
53+
this.status = status;
54+
this.responseBodySize = responseBodySize;
55+
this.httpReferrer = httpReferrer;
56+
this.httpUserAgent = httpUserAgent;
57+
this.customHeaders = new HashMap<>();
58+
}
59+
60+
public Calendar getDateTime() {
61+
return dateTime;
62+
}
63+
64+
public void setDateTime(Calendar dateTime) {
65+
this.dateTime = dateTime;
66+
}
67+
68+
public String getIp() {
69+
return ip;
70+
}
71+
72+
public void setIp(String ip) {
73+
this.ip = ip;
74+
}
75+
76+
public String getRequestMethod() {
77+
return requestMethod;
78+
}
79+
80+
public void setRequestMethod(String requestMethod) {
81+
this.requestMethod = requestMethod;
82+
}
83+
84+
public String getRequestUri() {
85+
return requestUri;
86+
}
87+
88+
public void setRequestUri(String requestUri) {
89+
this.requestUri = requestUri;
90+
}
91+
92+
public String getScheme() {
93+
return scheme;
94+
}
95+
96+
public void setScheme(String scheme) {
97+
this.scheme = scheme;
98+
}
99+
100+
public int getStatus() {
101+
return status;
102+
}
103+
104+
public void setStatus(int status) {
105+
this.status = status;
106+
}
107+
108+
public long getRequestBodySize() {
109+
return requestBodySize;
110+
}
111+
112+
public void setRequestBodySize(Long requestBodySize) {
113+
this.requestBodySize = requestBodySize;
114+
}
115+
116+
public long getResponseBodySize() {
117+
return responseBodySize;
118+
}
119+
120+
public void setResponseBodySize(Long responseBodySize) {
121+
this.responseBodySize = responseBodySize;
122+
}
123+
124+
public long getRequestTime() {
125+
return requestTime;
126+
}
127+
128+
public void setRequestTime(Long requestTime) {
129+
this.requestTime = requestTime;
130+
}
131+
132+
public String getHttpUserAgent() {
133+
return httpUserAgent;
134+
}
135+
136+
public String getHttpReferrer() {
137+
return httpReferrer;
138+
}
139+
140+
public void setHttpReferrer(String httpReferrer) {
141+
this.httpReferrer = httpReferrer;
142+
}
143+
144+
public void setHttpUserAgent(String httpUserAgent) {
145+
this.httpUserAgent = httpUserAgent;
146+
}
147+
148+
public String getHttpXForwardedFor() {
149+
return httpXForwardedFor;
150+
}
151+
152+
public void setHttpXForwardedFor(String httpXForwardedFor) {
153+
this.httpXForwardedFor = httpXForwardedFor;
154+
}
155+
156+
public String getHost() {
157+
return this.host;
158+
}
159+
160+
public void setHost(String host) {
161+
this.host = host;
162+
}
163+
164+
public int getPort() {
165+
return this.port;
166+
}
167+
168+
public void setPort(int port) {
169+
this.port = port;
170+
}
171+
172+
public Map<String, String> getCustomHeaders() {
173+
return customHeaders;
174+
}
175+
176+
public void setCustomHeaders(Map<String, String> customHeaders) {
177+
this.customHeaders = customHeaders;
178+
}
179+
180+
public void putCustomHeader(String headerKey, String headerValue) {
181+
this.customHeaders.put(headerKey, headerValue);
182+
}
183+
}

0 commit comments

Comments
 (0)