-
Notifications
You must be signed in to change notification settings - Fork 79
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 #508 from groldan/logging_mdc
Include application, http, and geoserver ows request properties in the logging MDC
- Loading branch information
Showing
14 changed files
with
706 additions
and
1 deletion.
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
37 changes: 37 additions & 0 deletions
37
.../org/geoserver/cloud/autoconfigure/observability/GeoServerDispatcherMDCConfiguration.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,37 @@ | ||
/* | ||
* (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.observability; | ||
|
||
import org.geoserver.cloud.observability.logging.config.MDCConfigProperties; | ||
import org.geoserver.cloud.observability.logging.ows.MDCDispatcherCallback; | ||
import org.geoserver.ows.Dispatcher; | ||
import org.geoserver.ows.DispatcherCallback; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
/** | ||
* {@link AutoConfiguration @AutoConfiguration} to enable logging MDC (Mapped Diagnostic Context) | ||
* for the GeoSever {@link Dispatcher} events using a {@link DispatcherCallback} | ||
* | ||
* @see MDCDispatcherCallback | ||
*/ | ||
@Configuration(proxyBeanMethods = false) | ||
@ConditionalOnClass({ | ||
Dispatcher.class, | ||
// from spring-webmvc, required by Dispatcher.class | ||
org.springframework.web.servlet.mvc.AbstractController.class | ||
}) | ||
@ConditionalOnWebApplication(type = Type.SERVLET) | ||
class GeoServerDispatcherMDCConfiguration { | ||
|
||
@Bean | ||
MDCDispatcherCallback mdcDispatcherCallback(MDCConfigProperties config) { | ||
return new MDCDispatcherCallback(config); | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
...ain/java/org/geoserver/cloud/autoconfigure/observability/LoggingMDCAutoConfiguration.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,95 @@ | ||
/* | ||
* (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.observability; | ||
|
||
import org.geoserver.cloud.observability.logging.config.MDCConfigProperties; | ||
import org.geoserver.cloud.observability.logging.servlet.HttpRequestMdcConfigProperties; | ||
import org.geoserver.cloud.observability.logging.servlet.HttpRequestMdcFilter; | ||
import org.geoserver.cloud.observability.logging.servlet.MDCAuthenticationFilter; | ||
import org.geoserver.cloud.observability.logging.servlet.MDCCleaningFilter; | ||
import org.geoserver.cloud.observability.logging.servlet.SpringEnvironmentMdcConfigProperties; | ||
import org.geoserver.cloud.observability.logging.servlet.SpringEnvironmentMdcFilter; | ||
import org.geoserver.security.GeoServerSecurityFilterChainProxy; | ||
import org.slf4j.MDC; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
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.boot.info.BuildProperties; | ||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Import; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.core.annotation.Order; | ||
import org.springframework.core.env.Environment; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContext; | ||
|
||
import java.util.Optional; | ||
|
||
/** | ||
* {@link AutoConfiguration @AutoConfiguration} to enable logging MDC (Mapped Diagnostic Context) | ||
* contributions during the request life cycle | ||
* | ||
* @see GeoServerDispatcherMDCConfiguration | ||
*/ | ||
@AutoConfiguration | ||
@EnableConfigurationProperties({ | ||
MDCConfigProperties.class, | ||
HttpRequestMdcConfigProperties.class, | ||
SpringEnvironmentMdcConfigProperties.class | ||
}) | ||
@Import(GeoServerDispatcherMDCConfiguration.class) | ||
@ConditionalOnWebApplication(type = Type.SERVLET) | ||
public class LoggingMDCAutoConfiguration { | ||
|
||
/** | ||
* @return servlet filter to {@link MDC#clear() clear} the MDC after the servlet request is | ||
* executed | ||
*/ | ||
@Bean | ||
@Order(Ordered.HIGHEST_PRECEDENCE) | ||
HttpRequestMdcFilter httpMdcFilter(HttpRequestMdcConfigProperties config) { | ||
return new HttpRequestMdcFilter(config); | ||
} | ||
|
||
@Bean | ||
@Order(Ordered.HIGHEST_PRECEDENCE) | ||
MDCCleaningFilter mdcCleaningServletFilter() { | ||
return new MDCCleaningFilter(); | ||
} | ||
|
||
@Bean | ||
@Order(Ordered.HIGHEST_PRECEDENCE) | ||
SpringEnvironmentMdcFilter springEnvironmentMdcFilter( | ||
Environment env, | ||
SpringEnvironmentMdcConfigProperties config, | ||
Optional<BuildProperties> buildProperties) { | ||
return new SpringEnvironmentMdcFilter(env, buildProperties, config); | ||
} | ||
|
||
/** | ||
* A servlet registration for {@link MDCAuthenticationFilter}, with {@link | ||
* FilterRegistrationBean#setMatchAfter setMatchAfter(true)} to ensure it runs after {@link | ||
* GeoServerSecurityFilterChainProxy} and hence the {@link SecurityContext} already has the | ||
* {@link Authentication} object. | ||
*/ | ||
@Bean | ||
@ConditionalOnClass(name = "org.springframework.security.core.Authentication") | ||
FilterRegistrationBean<MDCAuthenticationFilter> mdcAuthenticationPropertiesServletFilter( | ||
MDCConfigProperties config) { | ||
FilterRegistrationBean<MDCAuthenticationFilter> registration = | ||
new FilterRegistrationBean<>(); | ||
|
||
var filter = new MDCAuthenticationFilter(config); | ||
registration.setMatchAfter(true); | ||
|
||
registration.addUrlPatterns("/*"); | ||
registration.setOrder(Ordered.LOWEST_PRECEDENCE); | ||
registration.setFilter(filter); | ||
return registration; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...y/src/main/java/org/geoserver/cloud/observability/logging/config/MDCConfigProperties.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,18 @@ | ||
/* | ||
* (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.observability.logging.config; | ||
|
||
import lombok.Data; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
@Data | ||
@ConfigurationProperties(prefix = "logging.mdc.include") | ||
public class MDCConfigProperties { | ||
|
||
private boolean user = true; | ||
private boolean roles = true; | ||
private boolean ows = true; | ||
} |
43 changes: 43 additions & 0 deletions
43
...ty/src/main/java/org/geoserver/cloud/observability/logging/ows/MDCDispatcherCallback.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,43 @@ | ||
/* | ||
* (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.observability.logging.ows; | ||
|
||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
import org.geoserver.cloud.observability.logging.config.MDCConfigProperties; | ||
import org.geoserver.ows.AbstractDispatcherCallback; | ||
import org.geoserver.ows.DispatcherCallback; | ||
import org.geoserver.ows.Request; | ||
import org.geoserver.platform.Operation; | ||
import org.geoserver.platform.Service; | ||
import org.slf4j.MDC; | ||
|
||
@RequiredArgsConstructor | ||
public class MDCDispatcherCallback extends AbstractDispatcherCallback | ||
implements DispatcherCallback { | ||
|
||
private final @NonNull MDCConfigProperties config; | ||
|
||
@Override | ||
public Service serviceDispatched(Request request, Service service) { | ||
if (config.isOws()) { | ||
MDC.put("gs.ows.service.name", service.getId()); | ||
MDC.put("gs.ows.service.version", String.valueOf(service.getVersion())); | ||
if (null != request.getOutputFormat()) { | ||
MDC.put("gs.ows.service.format", request.getOutputFormat()); | ||
} | ||
} | ||
return super.serviceDispatched(request, service); | ||
} | ||
|
||
@Override | ||
public Operation operationDispatched(Request request, Operation operation) { | ||
if (config.isOws()) { | ||
MDC.put("gs.ows.service.operation", operation.getId()); | ||
} | ||
return super.operationDispatched(request, operation); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
...ava/org/geoserver/cloud/observability/logging/servlet/HttpRequestMdcConfigProperties.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,43 @@ | ||
/* | ||
* (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.observability.logging.servlet; | ||
|
||
import lombok.Data; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
@Data | ||
@ConfigurationProperties(prefix = "logging.mdc.include.http") | ||
public class HttpRequestMdcConfigProperties { | ||
|
||
private boolean id = true; | ||
|
||
/** | ||
* The Internet Protocol (IP) address of the client or last proxy that sent the request. For | ||
* HTTP servlets, same as the value of the CGI variable REMOTE_ADDR. | ||
*/ | ||
private boolean remoteAddr = true; | ||
|
||
/** | ||
* The fully qualified name of the client or the last proxy that sent the request. If the engine | ||
* cannot or chooses not to resolve the hostname (to improve performance), this method returns | ||
* the dotted-string form of the IP address. For HTTP servlets, same as the value of the CGI | ||
* variable REMOTE_HOST. Defaults to false to avoid the possible overhead in reverse DNS | ||
* lookups. remoteAddress should be enough in most cases. | ||
*/ | ||
private boolean remoteHost = true; | ||
|
||
private boolean method = true; | ||
private boolean url = true; | ||
private boolean parameters = true; | ||
private boolean queryString = true; | ||
private boolean sessionId = true; | ||
|
||
private boolean cookies = true; | ||
private boolean headers = true; | ||
private Pattern headersPattern = Pattern.compile(".*"); | ||
} |
Oops, something went wrong.