diff --git a/conf/core/server.conf b/conf/core/server.conf index c030d6eb63d61ad2d9adc6a174877b1006396537..eed73c1375a645771736c03462cc5452687ef04a 100644 --- a/conf/core/server.conf +++ b/conf/core/server.conf @@ -100,6 +100,20 @@ GRPC_SERVER_PORT_HTTPS=8443 # HTTP port of the grpc end-point GRPC_SERVER_PORT_HTTP= +# -------------------------------------------------- +# Response Log formatting (this cannot be configured by the logging frame work +# and thus has to be configured here). +# -------------------------------------------------- + +# Logging format of the GRPC API. +# Known keys: user-agent, local-address, remote-address, method. +# 'OFF' turns off the logging. +GRPC_RESPONSE_LOG_FORMAT={method} {local-address} {remote-address} {user-agent} +# Logging format of the REST API. +# Known keys: see column "Variable name" at https://javadocs.restlet.talend.com/2.4/jse/api/index.html +# 'OFF' turns off the logging. +REST_RESPONSE_LOG_FORMAT= + # -------------------------------------------------- # HTTPS options # -------------------------------------------------- @@ -229,4 +243,4 @@ ENTITY_VERSIONING_ENABLED=true # Enabling the state machine extension -# EXT_STATE_ENTITY=ENABLE \ No newline at end of file +# EXT_STATE_ENTITY=ENABLE diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java index 9daabaed65aa39a9be868567581588625aba7a53..05fb9485fdbd7b2a86b62e9b8ad18af5069f88c2 100644 --- a/src/main/java/org/caosdb/server/CaosDBServer.java +++ b/src/main/java/org/caosdb/server/CaosDBServer.java @@ -894,6 +894,13 @@ class CaosDBComponent extends Component { public CaosDBComponent() { super(); + String responseLogFormat = + CaosDBServer.getServerProperty(ServerProperties.KEY_REST_RESPONSE_LOG_FORMAT); + if ("OFF".equalsIgnoreCase(responseLogFormat)) { + getLogService().setEnabled(false); + } else if (responseLogFormat != null && !responseLogFormat.isEmpty()) { + getLogService().setResponseLogFormat(responseLogFormat); + } setName(CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_NAME)); setOwner(CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_OWNER)); } diff --git a/src/main/java/org/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java index d58250242f691498288d765dd252986eda7fb09f..93a0c7473be1c31565e4b159ba55e01d557687e7 100644 --- a/src/main/java/org/caosdb/server/ServerProperties.java +++ b/src/main/java/org/caosdb/server/ServerProperties.java @@ -150,6 +150,8 @@ public class ServerProperties extends Properties implements Observable { public static final String KEY_PASSWORD_STRENGTH_REGEX = "PASSWORD_VALID_REGEX"; public static final String KEY_PASSWORD_WEAK_MESSAGE = "PASSWORD_INVALID_MESSAGE"; + public static final String KEY_REST_RESPONSE_LOG_FORMAT = "REST_RESPONSE_LOG_FORMAT"; + public static final String KEY_GRPC_RESPONSE_LOG_FORMAT = "GRPC_RESPONSE_LOG_FORMAT"; /** * Read the config files and initialize the server properties. diff --git a/src/main/java/org/caosdb/server/grpc/LoggingInterceptor.java b/src/main/java/org/caosdb/server/grpc/LoggingInterceptor.java index 9edd35090659e908ecf7f3fb502d34c36ac7e829..4e52485d4af4357b90a560baee6095c3b14683ae 100644 --- a/src/main/java/org/caosdb/server/grpc/LoggingInterceptor.java +++ b/src/main/java/org/caosdb/server/grpc/LoggingInterceptor.java @@ -1,5 +1,6 @@ package org.caosdb.server.grpc; +import io.grpc.Attributes.Key; import io.grpc.Context; import io.grpc.Contexts; import io.grpc.Metadata; @@ -7,18 +8,70 @@ import io.grpc.ServerCall; import io.grpc.ServerCall.Listener; import io.grpc.ServerCallHandler; import io.grpc.ServerInterceptor; +import java.net.SocketAddress; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.restlet.routing.Template; +import org.restlet.util.Resolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +class CallResolver<ReqT, RespT> extends Resolver<String> { + + private ServerCall<ReqT, RespT> call; + private Metadata headers; + + public static final Metadata.Key<String> KEY_USER_AGENT = + Metadata.Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER); + public static final Key<SocketAddress> KEY_LOCAL_ADDRESS = io.grpc.Grpc.TRANSPORT_ATTR_LOCAL_ADDR; + public static final Key<SocketAddress> KEY_REMOTE_ADDRESS = + io.grpc.Grpc.TRANSPORT_ATTR_REMOTE_ADDR; + + public CallResolver( + ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { + this.call = call; + this.headers = headers; + } + + @Override + public String resolve(String name) { + switch (name) { + case "user-agent": + return headers.get(KEY_USER_AGENT); + case "remote-address": + return call.getAttributes().get(KEY_REMOTE_ADDRESS).toString(); + case "local-address": + return call.getAttributes().get(KEY_LOCAL_ADDRESS).toString(); + case "method": + return call.getMethodDescriptor().getFullMethodName(); + default: + break; + } + return null; + } +} + public class LoggingInterceptor implements ServerInterceptor { + private Template template; + + public LoggingInterceptor() { + String format = CaosDBServer.getServerProperty(ServerProperties.KEY_GRPC_RESPONSE_LOG_FORMAT); + if ("OFF".equalsIgnoreCase(format)) { + this.template = null; + } else if (format != null) { + this.template = new Template(format); + } + } + private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class.getName()); @Override public <ReqT, RespT> Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { - - logger.info(call.getMethodDescriptor().getFullMethodName() + " - " + call.getAttributes()); + if (template != null) { + logger.info(template.format(new CallResolver<ReqT, RespT>(call, headers, next))); + } return Contexts.interceptCall(Context.current(), call, headers, next); } }