All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.rest.logger.CallLoggerRule Maven / Gradle / Ivy

// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF 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 org.apache.juneau.rest.logger;

import static org.apache.juneau.collections.JsonMap.*;

import java.util.function.*;
import java.util.logging.*;

import jakarta.servlet.http.*;

import org.apache.juneau.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.internal.*;

/**
 * Represents a logging rule used by {@link CallLogger}.
 *
 * 
See Also:
*/ public class CallLoggerRule { //----------------------------------------------------------------------------------------------------------------- // Static //----------------------------------------------------------------------------------------------------------------- /** * Static creator. * * @param beanStore The bean store to use for creating beans. * @return A new builder for this object. */ public static Builder create(BeanStore beanStore) { return new Builder(beanStore); } //----------------------------------------------------------------------------------------------------------------- // Builder //----------------------------------------------------------------------------------------------------------------- /** * Builder class. */ @FluentSetters public static class Builder extends BeanBuilder { Predicate statusFilter; Predicate requestFilter; Predicate responseFilter; Predicate exceptionFilter; Enablement enabled; Predicate enabledTest; Level level; CallLoggingDetail requestDetail, responseDetail; boolean logStackTrace; /** * Constructor. * * @param beanStore The bean store to use for creating beans. */ protected Builder(BeanStore beanStore) { super(CallLoggerRule.class, beanStore); } @Override /* BeanBuilder */ protected CallLoggerRule buildDefault() { return new CallLoggerRule(this); } //------------------------------------------------------------------------------------------------------------- // Properties //------------------------------------------------------------------------------------------------------------- /** * Apply a status-based predicate check for this rule to match against. * *
Example:
*

* // Create a logger rule that only matches if the status code is greater than or equal to 500. * RestLogger * .createRule() * .statusFilter(x -> x >= 500) * .build(); *

* * @param value * The predicate check, or null to not use any filtering based on status code. * @return This object. */ public Builder statusFilter(Predicate value) { this.statusFilter = value; return this; } /** * Apply a throwable-based predicate check for this rule to match against. * *
Example:
*

* // Create a logger rule that only matches if a NotFound exception was thrown. * RestLogger * .createRule() * .exceptionFilter(x -> x instanceof NotFound) * .build(); *

* *

* This check is only performed if an actual throwable was thrown. Therefore it's not necessary to perform a * null check in the predicate. * * @param value * The predicate check, or null to not use any filtering based on exceptions. * @return This object. */ public Builder exceptionFilter(Predicate value) { this.exceptionFilter = value; return this; } /** * Apply a request-based predicate check for this rule to match against. * *

Example:
*

* // Create a logger rule that only matches if the servlet path contains "foobar". * RestLogger * .createRule() * .requestFilter(x -> x.getServletPath().contains("foobar")) * .build(); *

* * @param value * The predicate check, or null to not use any filtering based on the request. * @return This object. */ public Builder requestFilter(Predicate value) { this.requestFilter = value; return this; } /** * Apply a response-based predicate check for this rule to match against. * *
Example:
*

* // Create a logger rule that only matches if the servlet path contains "foobar". * RestLogger * .createRule() * .responseFilter(x -> x.getStatus() >= 500) * .build(); *

* *

* Note that the {@link #statusFilter(Predicate)} and {@link #exceptionFilter(Predicate)} methods are simply * convenience response filters. * * @param value * The predicate check, or null to not use any filtering based on the response. * @return This object. */ public Builder responseFilter(Predicate value) { this.responseFilter = value; return this; } /** * Specifies whether logging is enabled when using this rule. * *

Example:
*

* // Create a logger rule where logging is only enabled if the query string contains "foobar". * RestLogger * .createRule() * .enabled(CONDITIONALLY) * .enabledPredicate(x -> x.getQueryString().contains("foobar")) * .build(); *

* *
    *
  • {@link Enablement#ALWAYS ALWAYS} - Logging is enabled. *
  • {@link Enablement#NEVER NEVER} - Logging is disabled. *
  • {@link Enablement#CONDITIONAL CONDITIONALLY} - Logging is enabled if it passes the {@link #enabledPredicate(Predicate)} test. *
* * @param value * The enablement flag value, or null to inherit from the call logger whose default value is {@link Enablement#ALWAYS ALWAYS} * unless overridden via a "juneau.restCallLogger.enabled" system property or "JUNEAU_RESTCALLLOGGER_ENABLED" environment variable. * @return This object. */ public Builder enabled(Enablement value) { this.enabled = value; return this; } /** * Specifies the predicate test to use when the enabled setting is set to {@link Enablement#CONDITIONAL CONDITIONALLY}. * *

* This setting has no effect if the enablement value is not {@link Enablement#CONDITIONAL CONDITIONALLY}. * *

Example:
*

* // Create a logger rule where logging is only enabled if the query string contains "foobar". * RestLogger * .createRule() * .enabled(CONDITIONALLY) * .enabledPredicate(x -> x.getQueryString().contains("foobar")) * .build(); *

* * @param value * The enablement predicate test, or null to inherit from the call logger whose default value is x -> false. * @return This object. */ public Builder enabledPredicate(Predicate value) { this.enabledTest = value; return this; } /** * Shortcut for calling enabled(NEVER). * * @return This object. */ public Builder disabled() { return this.enabled(Enablement.NEVER); } /** * The level of detail to log on a request. * *
    *
  • {@link CallLoggingDetail#STATUS_LINE STATUS_LINE} - Log only the status line. *
  • {@link CallLoggingDetail#HEADER HEADER} - Log the status line and headers. *
  • {@link CallLoggingDetail#ENTITY ENTITY} - Log the status line and headers and content if available. *
* * @param value * The new value for this property, or null to inherit from the call logger. * @return This object. */ public Builder requestDetail(CallLoggingDetail value) { this.requestDetail = value; return this; } /** * The level of detail to log on a response. * *
    *
  • {@link CallLoggingDetail#STATUS_LINE STATUS_LINE} - Log only the status line. *
  • {@link CallLoggingDetail#HEADER HEADER} - Log the status line and headers. *
  • {@link CallLoggingDetail#ENTITY ENTITY} - Log the status line and headers and content if available. *
* * @param value * The new value for this property, or null to inherit from the call logger. * @return This object. */ public Builder responseDetail(CallLoggingDetail value) { this.responseDetail = value; return this; } /** * The logging level to use for logging the request/response. * *

* The default value is {@link Level#INFO}. * * @param value * The new value for this property, or null to inherit from the call logger. * @return This object. */ public Builder level(Level value) { this.level = value; return this; } /** * Log a stack trace as part of the log entry. * *

* The default value is false. * * @return This object. */ public Builder logStackTrace() { this.logStackTrace = true; return this; } // @Override /* GENERATED - org.apache.juneau.BeanBuilder */ public Builder impl(Object value) { super.impl(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanBuilder */ public Builder type(Class value) { super.type(value); return this; } // } //----------------------------------------------------------------------------------------------------------------- // Instance //----------------------------------------------------------------------------------------------------------------- private final Predicate statusFilter; private final Predicate requestFilter; private final Predicate responseFilter; private final Predicate exceptionFilter; private final Level level; private final Enablement enabled; private final Predicate enabledTest; private final CallLoggingDetail requestDetail, responseDetail; /** * Constructor. * * @param b Builder */ CallLoggerRule(Builder b) { this.statusFilter = b.statusFilter; this.exceptionFilter = b.exceptionFilter; this.requestFilter = b.requestFilter; this.responseFilter = b.responseFilter; this.level = b.level; this.enabled = b.enabled; this.enabledTest = b.enabledTest; this.requestDetail = b.requestDetail; this.responseDetail = b.responseDetail; } /** * Returns true if this rule matches the specified parameters. * * @param req The HTTP request being logged. Never null. * @param res The HTTP response being logged. Never null. * @return true if this rule matches the specified parameters. */ public boolean matches(HttpServletRequest req, HttpServletResponse res) { if ((requestFilter != null && ! requestFilter.test(req)) || (responseFilter != null && ! responseFilter.test(res))) return false; if (statusFilter != null && ! statusFilter.test(res.getStatus())) return false; Throwable e = (Throwable)req.getAttribute("Exception"); if (e != null && exceptionFilter != null && ! exceptionFilter.test(e)) return false; return true; } /** * Returns the detail level for HTTP requests. * * @return the detail level for HTTP requests, or null if it's not set. */ public CallLoggingDetail getRequestDetail() { return requestDetail; } /** * Returns the detail level for HTTP responses. * * @return the detail level for HTTP responses, or null if it's not set. */ public CallLoggingDetail getResponseDetail() { return responseDetail; } /** * Returns the log level on this rule. * * @return The log level on this rule, or null if it's not set. */ public Level getLevel() { return level; } /** * Returns the enablement flag value on this rule. * * @return The enablement flag value on this rule, or null if it's not set. */ public Enablement getEnabled() { return enabled; } /** * Returns the enablement predicate test on this rule. * * @return The enablement predicate test on this rule, or null if it's not set. */ public Predicate getEnabledTest() { return enabledTest; } @Override /* Object */ public String toString() { return filteredMap() .append("codeFilter", statusFilter) .append("exceptionFilter", exceptionFilter) .append("requestFilter", requestFilter) .append("responseFilter", responseFilter) .append("level", level) .append("requestDetail", requestDetail) .append("responseDetail", responseDetail) .append("enabled", enabled) .append("enabledTest", enabledTest) .asReadableString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy