/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.persistence.logging.internal;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.openhab.core.items.Item;
import org.openhab.core.persistence.PersistenceService;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
/**
* This is a {@link PersistenceService} implementation, which logs item states through
* a logback file appender.
*
* @author Kai Kreuzer
* @since 1.0.0
*/
public class LoggingPersistenceService implements PersistenceService {
private static final Logger logger = LoggerFactory.getLogger(LoggingPersistenceService.class);
private static final String LOG_FOLDER = "logs";
private static final String LOG_FILEEXT = ".log";
private static final String DEFAULT_PATTERN = "%date{ISO8601} - %-25logger: %msg%n";
private String pattern = null;
private boolean initialized = false;
private Map<String, FileAppender<ILoggingEvent>> appenders = new HashMap<String, FileAppender<ILoggingEvent>>();
/**
* @{inheritDoc}
*/
public void activate(final BundleContext bundleContext, final Map<String, Object> config) {
pattern = (String) config.get("pattern");
if (StringUtils.isBlank(pattern)) {
pattern = DEFAULT_PATTERN;
}
initialized = true;
}
public void deactivate(final int reason) {
for (FileAppender<ILoggingEvent> appender : appenders.values()) {
appender.stop();
}
appenders.clear();
}
/**
* @{inheritDoc}
*/
@Override
public String getName() {
return "logging";
}
/**
* @{inheritDoc}
*/
@Override
public void store(Item item) {
// use the item name as the log file name
store(item, item.getName());
}
/**
* @{inheritDoc}
*/
@Override
public void store(Item item, String alias) {
if (initialized) {
FileAppender<ILoggingEvent> appender = appenders.get(alias);
if (appender == null) {
synchronized (appenders) {
// do a second check in case one exists by now
if (!appenders.containsKey(alias)) {
appender = createNewAppender(alias);
appenders.put(alias, appender);
}
}
}
ItemLoggingEvent event = new ItemLoggingEvent(item);
appender.doAppend(event);
logger.debug("Logged item '{}' to file '{}.log'", new String[] { item.getName(), alias });
}
}
protected FileAppender<ILoggingEvent> createNewAppender(String alias) {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(context);
encoder.setPattern(pattern);
encoder.start();
FileAppender<ILoggingEvent> appender = new FileAppender<ILoggingEvent>();
appender.setAppend(true);
appender.setFile(LOG_FOLDER + File.separator + alias + LOG_FILEEXT);
appender.setEncoder(encoder);
appender.setContext(context);
appender.start();
return appender;
}
}