444 Expose Application Directories via User Preferences (#458)

* Refactors DirectoryPreference from PLaylistPreference.
Adds editor to PreferenceEditor for directories.
Organizes preference editor tree.

* Adds recording directory preference to editor and updates recording
manager to dynamically use this property for recordings.

* Adds event logs directory preference to editor and updates event log
manager to dynamically use this property for event logging.

* Adds application log directory preference.  Updates logging to use user
preference for application log directory.  Moves logging initialization
into the main application class and removes file based logging configs
from the logback.xml configuration file.

* Refactors application logging into its own class and adds prefeence
update monitoring to dynamically stop/start the logger in the new
directory location.

* Adds streaming and screen capture directories to the user preferences
editor and updates streaming and screen captures to dynamically adapt
to user changes.
This commit is contained in:
Denny Sheirer
2018-12-27 06:12:03 -05:00
committed by GitHub
parent 5b5a1431b4
commit 347a71f097
23 changed files with 1491 additions and 253 deletions

View File

@@ -0,0 +1,166 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.log;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.ThresholdFilter;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import com.google.common.eventbus.Subscribe;
import io.github.dsheirer.eventbus.MyEventBus;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.preference.UserPreferences;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
/**
* Logback and SLF4j logging implementation.
*/
public class ApplicationLog
{
private final static Logger mLog = LoggerFactory.getLogger(ApplicationLog.class);
private static final String APPLICATION_LOG_FILENAME = "sdrtrunk_app.log";
private static final int APPLICATION_LOG_MAX_HISTORY = 10;
private UserPreferences mUserPreferences;
private RollingFileAppender mRollingFileAppender;
private Path mApplicationLogPath;
/**
* Constructs the application log instance. Note: use the start() method to initiate logging.
* @param userPreferences
*/
public ApplicationLog(UserPreferences userPreferences)
{
mUserPreferences = userPreferences;
MyEventBus.getEventBus().register(this);
}
@Subscribe
public void preferenceUpdated(PreferenceType preferenceType)
{
if(preferenceType == PreferenceType.DIRECTORY && mRollingFileAppender != null && mApplicationLogPath != null)
{
Path applicationLogPath = mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog();
//Restart the application log if the path is updated
if(!applicationLogPath.equals(mApplicationLogPath))
{
mLog.info("Application logging directory has changed [" + applicationLogPath.toString() + " ] - restarting logging");
stop();
start();
}
}
}
/**
* Starts application logging
*/
public void start()
{
if(mRollingFileAppender == null)
{
mApplicationLogPath = mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog();
Path logfile = mApplicationLogPath.resolve(APPLICATION_LOG_FILENAME);
mLog.info("Application Log File: " + logfile.toString());
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("%-25(%d{yyyyMMdd HHmmss.SSS} [%thread]) %-5level %logger{30} - %msg %memory_usage%n");
encoder.start();
mRollingFileAppender = new RollingFileAppender();
mRollingFileAppender.setContext(loggerContext);
mRollingFileAppender.setAppend(true);
mRollingFileAppender.setName("FILE");
mRollingFileAppender.setEncoder(encoder);
mRollingFileAppender.setFile(logfile.toString());
ThresholdFilter thresholdFilter = new ThresholdFilter();
thresholdFilter.setLevel(Level.DEBUG.toString());
thresholdFilter.setContext(loggerContext);
thresholdFilter.setName("sdrtrunk threshold filter");
thresholdFilter.start();
mRollingFileAppender.addFilter(thresholdFilter);
String pattern = logfile.toString().replace(APPLICATION_LOG_FILENAME, "%d{yyyyMMdd}_" + APPLICATION_LOG_FILENAME);
TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy<>();
rollingPolicy.setContext(loggerContext);
rollingPolicy.setFileNamePattern(pattern);
rollingPolicy.setMaxHistory(APPLICATION_LOG_MAX_HISTORY);
rollingPolicy.setParent(mRollingFileAppender);
rollingPolicy.start();
mRollingFileAppender.setRollingPolicy(rollingPolicy);
mRollingFileAppender.start();
Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
((ch.qos.logback.classic.Logger)logger).setLevel(Level.ALL);
((ch.qos.logback.classic.Logger)logger).addAppender(mRollingFileAppender);
// StatusPrinter.print(loggerContext);
mLog.info("");
mLog.info("*******************************************************************");
mLog.info("**** sdrtrunk: a trunked radio and digital decoding application ***");
mLog.info("**** website: https://github.com/dsheirer/sdrtrunk ***");
mLog.info("*******************************************************************");
mLog.info("Memory Logging Format: [Used/Allocated PercentUsed%]");
mLog.info("Host OS Name: " + System.getProperty("os.name"));
mLog.info("Host OS Arch: " + System.getProperty("os.arch"));
mLog.info("Host OS Version: " + System.getProperty("os.version"));
mLog.info("Host CPU Cores: " + Runtime.getRuntime().availableProcessors());
mLog.info("Host Max Java Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().maxMemory()));
mLog.info("Storage Directories:");
mLog.info(" Application Root: " + mUserPreferences.getDirectoryPreference().getDirectoryApplicationRoot());
mLog.info(" Application Log: " + mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog());
mLog.info(" Event Log: " + mUserPreferences.getDirectoryPreference().getDirectoryEventLog());
mLog.info(" Playlist: " + mUserPreferences.getDirectoryPreference().getDirectoryPlaylist());
mLog.info(" Recordings: " + mUserPreferences.getDirectoryPreference().getDirectoryRecording());
}
}
/**
* Stops the log file appender and nullifies it for shutdown or for reinitialization.
*/
public void stop()
{
if(mRollingFileAppender != null)
{
mLog.info("Stopping application logging");
mRollingFileAppender.stop();
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
((ch.qos.logback.classic.Logger)logger).detachAppender(mRollingFileAppender);
mRollingFileAppender = null;
}
}
}