001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.server.management;
018
019/**
020 * Exposure settings for the {@code /loggers} endpoint.
021 *
022 * <p>
023 * The {@code GET} (read) endpoints are always exposed; the {@code PUT}/{@code POST} <b>set-level</b> endpoints
024 * <b>mutate runtime logging</b> and are therefore <b>deny-by-default</b> on the same sensitive-by-default
025 * posture as the diagnostic dumps.  A consumer opts in <i>explicitly</i> by registering a
026 * {@code LoggersSettings} bean (built with {@link Builder#enableWrite()}) in the resource's bean store.  When
027 * no such bean is present, {@link LoggersManager} resolves the default (writes disabled) and the set-level
028 * endpoints respond {@code 403 Forbidden}.
029 *
030 * <h5 class='topic'>Backend selection (explicit)</h5>
031 *
032 * <p>
033 * The {@code /loggers} endpoint drives a {@link LogBackend}.  By default that is
034 * {@link JulLogBackend java.util.logging}.  To drive a different backend (e.g. Logback or Log4j2 via the
035 * {@code juneau-rest-server-management-logging} add-on), declare it <i>explicitly</i> with
036 * {@link Builder#backend(LogBackend)} &mdash; the endpoint never classpath-scans for, and then drives, a backend
037 * the operator did not choose.
038 *
039 * <h5 class='section'>See Also:</h5><ul>
040 *    <li class='jc'>{@link LoggersManager}
041 *    <li class='jc'>{@link LogBackend}
042 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ManagementSurface">Management Surface (Actuator-style endpoints)</a>
043 * </ul>
044 *
045 * @since 10.0.0
046 */
047public class LoggersSettings {
048
049   /** The default (read-only, JUL-backed) settings used when no bean is registered. */
050   public static final LoggersSettings DEFAULT = create().build();
051
052   private final boolean writeEnabled;
053   private final LogBackend backend;
054
055   private LoggersSettings(Builder b) {
056      this.writeEnabled = b.writeEnabled;
057      this.backend = b.backend == null ? JulLogBackend.INSTANCE : b.backend;
058   }
059
060   /**
061    * Builder creator.
062    *
063    * @return A new builder (writes disabled).
064    */
065   public static Builder create() {
066      return new Builder();
067   }
068
069   /**
070    * @return <jk>true</jk> if the {@code PUT}/{@code POST} set-level endpoints are enabled.
071    */
072   public boolean isWriteEnabled() {
073      return writeEnabled;
074   }
075
076   /**
077    * @return The explicitly-declared {@link LogBackend} the {@code /loggers} endpoint drives, or
078    *    {@link JulLogBackend#INSTANCE} when none was declared.  Never <jk>null</jk>.
079    */
080   public LogBackend getBackend() {
081      return backend;
082   }
083
084   /**
085    * Builder for {@link LoggersSettings}.
086    */
087   public static class Builder {
088      private boolean writeEnabled;
089      private LogBackend backend;
090
091      /**
092       * Enables the {@code PUT}/{@code POST} set-level endpoints.
093       *
094       * @return This object.
095       */
096      public Builder enableWrite() {
097         writeEnabled = true;
098         return this;
099      }
100
101      /**
102       * Explicitly declares the {@link LogBackend} the {@code /loggers} endpoint drives.
103       *
104       * <p>
105       * When not set, the endpoint drives {@link JulLogBackend java.util.logging}.  Pass a Logback / Log4j2
106       * backend (from {@code juneau-rest-server-management-logging}) or a custom implementation to drive a
107       * different backend &mdash; this is the explicit opt-in; the endpoint does not auto-detect.
108       *
109       * @param value The backend.  <jk>null</jk> resets to the JUL default.
110       * @return This object.
111       */
112      public Builder backend(LogBackend value) {
113         backend = value;
114         return this;
115      }
116
117      /**
118       * Builds the settings.
119       *
120       * @return A new {@link LoggersSettings}.
121       */
122      public LoggersSettings build() {
123         return new LoggersSettings(this);
124      }
125   }
126}