Skip to content

Commit

Permalink
Implement AccessLog logging
Browse files Browse the repository at this point in the history
  • Loading branch information
AzeemMuzammil committed May 3, 2024
1 parent 29a01e7 commit c89997c
Show file tree
Hide file tree
Showing 14 changed files with 510 additions and 120 deletions.
4 changes: 4 additions & 0 deletions ballerina/http_log_manager.bal
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ public type TraceLogAdvancedConfiguration record {|
# Represents HTTP access log configuration.
#
# + console - Boolean value to enable or disable console access logs
# + format - The format of access logs to be printed (either `flat` or `json`)
# + attributes - The list of attributes of access logs to be printed
# + path - Optional file path to store access logs
public type AccessLogConfiguration record {|
boolean console = false;
string format = "flat";
string[] attributes?;
string path?;
|};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,12 @@ public final class HttpConstants {
public static final String HTTP_TRACE_LOG_ENABLED = "http.tracelog.enabled";
public static final String HTTP_ACCESS_LOG = "http.accesslog";
public static final String HTTP_ACCESS_LOG_ENABLED = "http.accesslog.enabled";
public static final String HTTP_LOG_FORMAT_JSON = "json";

// TraceLog and AccessLog configs
public static final BString HTTP_LOG_CONSOLE = StringUtils.fromString("console");
public static final BString HTTP_LOG_FORMAT = StringUtils.fromString("format");
public static final BString HTTP_LOG_ATTRIBUTES = StringUtils.fromString("attributes");
public static final BString HTTP_LOG_FILE_PATH = StringUtils.fromString("path");
public static final BString HTTP_TRACE_LOG_HOST = StringUtils.fromString("host");
public static final BString HTTP_TRACE_LOG_PORT = StringUtils.fromString("port");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
import io.ballerina.stdlib.http.api.logging.formatters.HttpAccessLogFormatter;
import io.ballerina.stdlib.http.api.logging.formatters.HttpTraceLogFormatter;
import io.ballerina.stdlib.http.api.logging.formatters.JsonLogFormatter;
import io.ballerina.stdlib.http.api.logging.logger.HttpAccessLogger;
import io.ballerina.stdlib.http.api.logging.logger.HttpLoggerFactory;
import io.ballerina.stdlib.http.transport.contractimpl.common.accesslog.HttpAccessLogFormat;
import io.ballerina.stdlib.http.transport.contractimpl.common.accesslog.HttpAccessLogMessage;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -38,10 +44,13 @@
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_ACCESS_LOG_ENABLED;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_CONSOLE;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_FILE_PATH;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_FORMAT;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_LOG_FORMAT_JSON;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_TRACE_LOG;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_TRACE_LOG_ENABLED;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_TRACE_LOG_HOST;
import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_TRACE_LOG_PORT;
import static io.ballerina.stdlib.http.transport.contract.Constants.ACCESS_LOG;

/**
* Java util logging manager for ballerina which overrides the readConfiguration method to replace placeholders
Expand All @@ -63,13 +72,15 @@ public class HttpLogManager extends LogManager {

protected Logger httpTraceLogger;
protected Logger httpAccessLogger;
protected InternalLogger httpInternalLogger;
private String protocol;

public HttpLogManager(boolean traceLogConsole, BMap traceLogAdvancedConfig, BMap accessLogConfig,
BString protocol) {
this.protocol = protocol.getValue();
this.setHttpTraceLogHandler(traceLogConsole, traceLogAdvancedConfig);
this.setHttpAccessLogHandler(accessLogConfig);
HttpAccessLogMessage.initializeHttpAccessLogConfig(accessLogConfig);
}

/**
Expand Down Expand Up @@ -134,13 +145,17 @@ public void setHttpAccessLogHandler(BMap accessLogConfig) {
// keep a reference to prevent this logger from being garbage collected
httpAccessLogger = Logger.getLogger(HTTP_ACCESS_LOG);
}
if (httpInternalLogger == null) {
httpInternalLogger = InternalLoggerFactory.getInstance(ACCESS_LOG);
}
PrintStream stdErr = System.err;
boolean accessLogsEnabled = false;

HttpAccessLogFormat accessLogFormat = getAccessLogFormat(accessLogConfig);
Boolean consoleLogEnabled = accessLogConfig.getBooleanValue(HTTP_LOG_CONSOLE);
if (consoleLogEnabled) {
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(new HttpAccessLogFormatter());
consoleHandler.setFormatter(new HttpAccessLogFormatter(accessLogFormat));
consoleHandler.setLevel(Level.INFO);
httpAccessLogger.addHandler(consoleHandler);
httpAccessLogger.setLevel(Level.INFO);
Expand All @@ -151,7 +166,7 @@ public void setHttpAccessLogHandler(BMap accessLogConfig) {
if (filePath != null && !filePath.getValue().trim().isEmpty()) {
try {
FileHandler fileHandler = new FileHandler(filePath.getValue(), true);
fileHandler.setFormatter(new HttpAccessLogFormatter());
fileHandler.setFormatter(new HttpAccessLogFormatter(accessLogFormat));
fileHandler.setLevel(Level.INFO);
httpAccessLogger.addHandler(fileHandler);
httpAccessLogger.setLevel(Level.INFO);
Expand All @@ -167,4 +182,11 @@ public void setHttpAccessLogHandler(BMap accessLogConfig) {
}
}

private HttpAccessLogFormat getAccessLogFormat(BMap accessLogConfig) {
BString logFormat = accessLogConfig.getStringValue(HTTP_LOG_FORMAT);
if (logFormat.getValue().equals(HTTP_LOG_FORMAT_JSON)) {
return HttpAccessLogFormat.JSON;
}
return HttpAccessLogFormat.FLAT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package io.ballerina.stdlib.http.api.logging.formatters;

import io.ballerina.stdlib.http.api.logging.HttpLogManager;
import io.ballerina.stdlib.http.transport.contractimpl.common.accesslog.HttpAccessLogFormat;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;
Expand All @@ -29,6 +30,11 @@
* @since 0.965
*/
public class HttpAccessLogFormatter extends Formatter {
private HttpAccessLogFormat accessLogFormat;

public HttpAccessLogFormatter(HttpAccessLogFormat accessLogFormat) {
this.accessLogFormat = accessLogFormat;
}

private static final String format = HttpLogManager.getLogManager().getProperty(
HttpAccessLogFormatter.class.getCanonicalName() + ".format");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.stdlib.http.api.logging.logger;

import io.ballerina.stdlib.http.transport.contractimpl.common.accesslog.HttpAccessLogFormat;

public class HttpAccessLogger extends HttpLogger {
HttpAccessLogFormat format = HttpAccessLogFormat.FLAT;
public HttpAccessLogger(String name) {
super(name);
}

public HttpAccessLogFormat getFormat() {
return format;
}

public void setFormat(HttpAccessLogFormat format) {
this.format = format;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.stdlib.http.api.logging.logger;

import io.netty.util.internal.logging.AbstractInternalLogger;
import io.netty.util.internal.logging.InternalLogLevel;

public class HttpLogger extends AbstractInternalLogger {

protected HttpLogger(String name) {
super(name);
}

@Override
public boolean isTraceEnabled() {
return false;
}

@Override
public void trace(String s) {

}

@Override
public void trace(String s, Object o) {

}

@Override
public void trace(String s, Object o, Object o1) {

}

@Override
public void trace(String s, Object... objects) {

}

@Override
public void trace(String s, Throwable throwable) {

}

@Override
public boolean isDebugEnabled() {

return false;
}

@Override
public void debug(String s) {

}

@Override
public void debug(String s, Object o) {

}

@Override
public void debug(String s, Object o, Object o1) {

}

@Override
public void debug(String s, Object... objects) {

}

@Override
public void debug(String s, Throwable throwable) {

}

@Override
public boolean isInfoEnabled() {

return false;
}

@Override
public void info(String s) {

}

@Override
public void info(String s, Object o) {

}

@Override
public void info(String s, Object o, Object o1) {

}

@Override
public void info(String s, Object... objects) {

}

@Override
public void info(String s, Throwable throwable) {

}

@Override
public boolean isWarnEnabled() {

return false;
}

@Override
public void warn(String s) {

}

@Override
public void warn(String s, Object o) {

}

@Override
public void warn(String s, Object... objects) {

}

@Override
public void warn(String s, Object o, Object o1) {

}

@Override
public void warn(String s, Throwable throwable) {

}

@Override
public boolean isErrorEnabled() {

return false;
}

@Override
public void error(String s) {

}

@Override
public void error(String s, Object o) {

}

@Override
public void error(String s, Object o, Object o1) {

}

@Override
public void error(String s, Object... objects) {

}

@Override
public void error(String s, Throwable throwable) {

}

@Override
public void log(InternalLogLevel level, String msg) {
super.log(level, msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.stdlib.http.api.logging.logger;

import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

public class HttpLoggerFactory extends InternalLoggerFactory {
@Override
protected InternalLogger newInstance(String name) {
if (name.contains("accesslog")) {
return new HttpAccessLogger(name);
}
return this.newInstance(name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public final class Constants {
public static final String HTTP_REASON_PHRASE = "HTTP_REASON_PHRASE";

public static final String CHNL_HNDLR_CTX = "CHNL_HNDLR_CTX";
public static final String ACCESS_LOG_MESSAGE_ID = "ACCESS_LOG_MESSAGE_ID";
public static final String OUTBOUND_ACCESS_LOG_MESSAGE = "OUTBOUND_ACCESS_LOG_MESSAGE";

public static final String SRC_HANDLER = "SRC_HANDLER";
public static final String POOLED_BYTE_BUFFER_FACTORY = "POOLED_BYTE_BUFFER_FACTORY";
Expand Down
Loading

0 comments on commit c89997c

Please sign in to comment.