org.opentestsystem.delivery.logging.LoggingConfigRefresher.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.delivery.logging.LoggingConfigRefresher.java

Source

/***************************************************************************************************
 * Educational Online Test Delivery System
 * Copyright (c) 2017 Regents of the University of California
 *
 * Distributed under the AIR Open Source License, Version 1.0
 * See accompanying file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 *
 * SmarterApp Open Source Assessment Software Project: http://smarterapp.org
 * Developed by Fairway Technologies, Inc. (http://fairwaytech.com)
 * for the Smarter Balanced Assessment Consortium (http://smarterbalanced.org)
 **************************************************************************************************/

package org.opentestsystem.delivery.logging;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Operation to reload logback configuration from the centralized spring cloud config server.
 * @see <a href="https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html">spring cloud config server</a>
 *
 * The config server is specified by the environment variable CONFIG_SERVICE_URL.
 * If the config server is not running, the local logback logging configuration is used.
 *
 * The configuration file loaded from the config server is named logback-${app.context.name}.xml.
 * The value of ${app.context.name} is defined in the local logback configuration file.
 * For example: <property scope="context" name="app.context.name" value="legacy-app" />
 *
 * The current app, spring profile and label are sent to the config server for use in property value substitution.
 * The app is defined by the ${app.context.name} value.
 * The label is defined by the environment variable CONFIG_LABEL and defaults to "master".
 */
public class LoggingConfigRefresher {
    private static final Logger logger = LoggerFactory.getLogger(LoggingConfigRefresher.class);

    private final String configUrl;
    private final String configLabel;
    private final String appName;
    private Environment environment;
    private final String profiles;

    private static final String PROGMAN_LOCATOR = "progman.locator";

    public LoggingConfigRefresher(String configUrl, String configLabel, String appName, Environment environment) {
        this.configUrl = configUrl;
        this.configLabel = configLabel;
        this.environment = environment;
        this.appName = appName;
        this.profiles = StringUtils.join(environment.getActiveProfiles(), ",");
    }

    public void refreshLoggerConfig() {
        final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

        if (StringUtils.isBlank(configUrl) || StringUtils.isBlank(appName)) {
            addProfiles(context);
            return;
        }

        try {
            final UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(configUrl);
            builder.pathSegment(appName, profiles, configLabel, String.format("logback-%s.xml", appName));
            final URL springConfigURL = builder.build().toUri().toURL();
            final JoranConfigurator configurator = new JoranConfigurator();
            configurator.setContext(context);

            // Call context.reset() to clear any previous configuration, e.g. default
            // configuration. For multi-step configuration, omit calling context.reset().
            context.reset();
            configurator.doConfigure(springConfigURL);
            addProfiles(context);
        } catch (JoranException je) {
            logger.warn("Exception occurred while configuring logback", je);
        } catch (MalformedURLException e) {
            logger.warn("Exception occurred while building url to spring-boot config server", e);
        }
    }

    protected void addProfiles(final LoggerContext context) {
        context.putProperty("spring.profiles.active", profiles);
        context.putProperty(PROGMAN_LOCATOR, System.getProperty(PROGMAN_LOCATOR));
    }
}