-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #576 from geoserver/backport-575-to-release/1.9.x
[Backport release/1.9.x] Add access log configuration for geoserver
- Loading branch information
Showing
34 changed files
with
916 additions
and
452 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
...rg/geoserver/cloud/autoconfigure/logging/accesslog/AccessLogServletAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the | ||
* GPL 2.0 license, available at the root application directory. | ||
*/ | ||
package org.geoserver.cloud.autoconfigure.logging.accesslog; | ||
|
||
import org.geoserver.cloud.logging.accesslog.AccessLogFilterConfig; | ||
import org.geoserver.cloud.logging.accesslog.AccessLogServletFilter; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
@AutoConfiguration | ||
@ConditionalOnProperty(name = AccessLogFilterConfig.ENABLED_KEY, havingValue = "true", matchIfMissing = false) | ||
@EnableConfigurationProperties(AccessLogFilterConfig.class) | ||
@ConditionalOnWebApplication(type = Type.SERVLET) | ||
public class AccessLogServletAutoConfiguration { | ||
|
||
@Bean | ||
AccessLogServletFilter accessLogFilter(AccessLogFilterConfig conf) { | ||
return new AccessLogServletFilter(conf); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
...ervability/src/main/java/org/geoserver/cloud/logging/accesslog/AccessLogFilterConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the | ||
* GPL 2.0 license, available at the root application directory. | ||
*/ | ||
package org.geoserver.cloud.logging.accesslog; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.regex.Pattern; | ||
import lombok.Data; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
/** | ||
* Configuration to set white/black list over the request URL to determine if | ||
* the access log filter will log an entry for it. | ||
*/ | ||
@Data | ||
@ConfigurationProperties(prefix = "logging.accesslog") | ||
@Slf4j(topic = "org.geoserver.cloud.accesslog") | ||
public class AccessLogFilterConfig { | ||
|
||
public static final String ENABLED_KEY = "logging.accesslog.enabled"; | ||
|
||
/** | ||
* A list of java regular expressions applied to the request URL for logging at | ||
* trace level | ||
*/ | ||
List<Pattern> trace = new ArrayList<>(); | ||
|
||
/** | ||
* A list of java regular expressions applied to the request URL for logging at | ||
* debug level | ||
*/ | ||
List<Pattern> debug = new ArrayList<>(); | ||
|
||
/** | ||
* A list of java regular expressions applied to the request URL for logging at | ||
* info level | ||
*/ | ||
List<Pattern> info = new ArrayList<>(); | ||
|
||
private enum Level { | ||
OFF { | ||
@Override | ||
void log(String message, Object... args) { | ||
// no-op | ||
} | ||
}, | ||
TRACE { | ||
@Override | ||
void log(String message, Object... args) { | ||
log.trace(message, args); | ||
} | ||
}, | ||
DEBUG { | ||
@Override | ||
void log(String message, Object... args) { | ||
log.debug(message, args); | ||
} | ||
}, | ||
INFO { | ||
@Override | ||
void log(String message, Object... args) { | ||
log.info(message, args); | ||
} | ||
}; | ||
|
||
abstract void log(String message, Object... args); | ||
} | ||
|
||
public void log(String method, int statusCode, String uri) { | ||
Level level = getLogLevel(uri); | ||
level.log("{} {} {} ", method, statusCode, uri); | ||
} | ||
|
||
Level getLogLevel(String uri) { | ||
if (log.isInfoEnabled() && matches(uri, info)) return Level.INFO; | ||
if (log.isDebugEnabled() && matches(uri, debug)) return Level.INFO; | ||
if (log.isTraceEnabled() && matches(uri, trace)) return Level.INFO; | ||
|
||
return Level.OFF; | ||
} | ||
|
||
private boolean matches(String url, List<Pattern> patterns) { | ||
return (patterns == null || patterns.isEmpty()) | ||
? false | ||
: patterns.stream().anyMatch(pattern -> pattern.matcher(url).matches()); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...rvability/src/main/java/org/geoserver/cloud/logging/accesslog/AccessLogServletFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the | ||
* GPL 2.0 license, available at the root application directory. | ||
*/ | ||
package org.geoserver.cloud.logging.accesslog; | ||
|
||
import java.io.IOException; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import lombok.NonNull; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.core.annotation.Order; | ||
import org.springframework.web.filter.CommonsRequestLoggingFilter; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
/** Similar to {@link CommonsRequestLoggingFilter} but uses slf4j */ | ||
@Order(Ordered.HIGHEST_PRECEDENCE + 3) | ||
public class AccessLogServletFilter extends OncePerRequestFilter { | ||
|
||
private final @NonNull AccessLogFilterConfig config; | ||
|
||
public AccessLogServletFilter(@NonNull AccessLogFilterConfig conf) { | ||
this.config = conf; | ||
} | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) | ||
throws ServletException, IOException { | ||
|
||
try { | ||
filterChain.doFilter(request, response); | ||
} finally { | ||
String uri = request.getRequestURI(); | ||
String method = request.getMethod(); | ||
int statusCode = response.getStatus(); | ||
config.log(method, statusCode, uri); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...c/main/java/org/geoserver/cloud/logging/mdc/config/AuthenticationMdcConfigProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the | ||
* GPL 2.0 license, available at the root application directory. | ||
*/ | ||
package org.geoserver.cloud.logging.mdc.config; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class AuthenticationMdcConfigProperties { | ||
|
||
/** Whether to append the enduser.id MDC property from the Authentication name */ | ||
private boolean id = false; | ||
|
||
/** | ||
* Whether to append the enduser.roles MDC property from the Authentication granted authorities | ||
*/ | ||
private boolean roles = false; | ||
} |
38 changes: 38 additions & 0 deletions
38
...ty/src/main/java/org/geoserver/cloud/logging/mdc/config/GeoServerMdcConfigProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the | ||
* GPL 2.0 license, available at the root application directory. | ||
*/ | ||
package org.geoserver.cloud.logging.mdc.config; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class GeoServerMdcConfigProperties { | ||
|
||
private OWSMdcConfigProperties ows = new OWSMdcConfigProperties(); | ||
|
||
/** Configuration properties to contribute GeoServer OWS request properties to the MDC */ | ||
@Data | ||
public static class OWSMdcConfigProperties { | ||
/** | ||
* Whether to append the gs.ows.service.name MDC property from the OWS dispatched request | ||
*/ | ||
private boolean serviceName = true; | ||
|
||
/** | ||
* Whether to append the gs.ows.service.version MDC property from the OWS dispatched request | ||
*/ | ||
private boolean serviceVersion = true; | ||
|
||
/** | ||
* Whether to append the gs.ows.service.format MDC property from the OWS dispatched request | ||
*/ | ||
private boolean serviceFormat = true; | ||
|
||
/** | ||
* Whether to append the gs.ows.service.operation MDC property from the OWS dispatched | ||
* request | ||
*/ | ||
private boolean operationName = true; | ||
} | ||
} |
Oops, something went wrong.