/*
* Copyright © 2014 Cask Data, Inc.
*
* Licensed 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 co.cask.cdap.logging.appender;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.StatusManager;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.util.concurrent.ConcurrentMap;
/**
* Creates and sets the logback log appender.
*/
public class LogAppenderInitializer implements Closeable {
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(LogAppenderInitializer.class);
private static final ConcurrentMap<String, String> initMap = Maps.newConcurrentMap();
private final LogAppender logAppender;
@Inject
public LogAppenderInitializer(LogAppender logAppender) {
this.logAppender = logAppender;
}
public void initialize() {
if (initMap.putIfAbsent(org.slf4j.Logger.ROOT_LOGGER_NAME, logAppender.getName()) != null) {
// Already initialized.
LOG.warn("Log appender {} is already initialized.", logAppender.getName());
return;
}
initialize(org.slf4j.Logger.ROOT_LOGGER_NAME);
}
@VisibleForTesting
public void initialize(String rootLoggerName) {
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
// TODO: fix logging issue in mapreduce: ENG-3279
if (!(loggerFactory instanceof LoggerContext)) {
LOG.warn("LoggerFactory is not a logback LoggerContext. No log appender is added. " +
"Logback might not be in the classpath");
return;
}
LoggerContext loggerContext = (LoggerContext) loggerFactory;
Logger rootLogger = loggerContext.getLogger(rootLoggerName);
LOG.info("Initializing log appender {}", logAppender.getName());
// Display any errors during initialization of log appender to console
StatusManager statusManager = loggerContext.getStatusManager();
OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
statusManager.add(onConsoleListener);
logAppender.setContext(loggerContext);
logAppender.start();
rootLogger.addAppender(logAppender);
}
@Override
public void close() {
if (logAppender != null) {
LOG.info("Stopping log appender {}", logAppender.getName());
logAppender.stop();
}
}
}