All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.binjr.core.preferences.UserPreferences Maven / Gradle / Ivy

There is a newer version: 3.20.1
Show newest version
/*
 *    Copyright 2019-2023 Frederic Thevenet
 *
 *    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 eu.binjr.core.preferences;

import com.google.gson.Gson;
import eu.binjr.common.logging.Logger;
import eu.binjr.common.preferences.*;
import eu.binjr.core.appearance.BuiltInChartColorPalettes;
import eu.binjr.core.appearance.BuiltInUserInterfaceThemes;
import eu.binjr.core.appearance.UserInterfaceThemes;
import eu.binjr.core.data.adapters.DataAdapterFactory;
import eu.binjr.core.data.async.ThreadPoolPolicy;
import eu.binjr.core.data.indexes.IndexDirectoryLocation;
import eu.binjr.core.data.indexes.parser.profile.CustomParsingProfile;
import eu.binjr.core.data.indexes.parser.profile.ParsingProfile;
import javafx.geometry.Rectangle2D;
import javafx.scene.paint.Color;
import org.apache.logging.log4j.Level;

import java.io.IOException;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.Locale;
import java.util.Map;
import java.util.prefs.BackingStoreException;
import java.util.prefs.InvalidPreferencesFormatException;

/**
 * Manage all user preferences
 *
 * @author Frederic Thevenet
 */
public class UserPreferences extends ObservablePreferenceFactory {
    private static final Logger logger = Logger.create(UserPreferences.class);
    private static final Gson gson = new Gson();
    public static final String BINJR_GLOBAL = "binjr/global";

    private final UserFavorites favorites = new UserFavorites(BINJR_GLOBAL);

    /**
     * True if series down-sampling is enabled, false otherwise.
     */
    public final ObservablePreference downSamplingEnabled = booleanPreference("downSamplingEnabled", true);

    /**
     * The series down-sampling threshold value.
     */
    public final ObservablePreference downSamplingThreshold = integerPreference("downSamplingThreshold", 1500);

    /**
     * The username used for authenticated access to the GitHub API.
     */
    public final ObservablePreference githubUserName = stringPreference("githubUserName", "");

    /**
     * The authentication token  used for authenticated access to the GitHub API.
     */
    public final ObservablePreference githubAuthToken = obfuscatedStringPreference("githubAuthToken", "");

    /**
     * The User Interface theme applied to the application.
     */
    public final ObservablePreference userInterfaceTheme =
            objectPreference(UserInterfaceThemes.class,
                    "userInterfaceTheme_v2",
                    BuiltInUserInterfaceThemes.LIGHT,
                    UserInterfaceThemes::name,
                    s -> UserInterfaceThemes.valueOf(s, BuiltInUserInterfaceThemes.LIGHT));

    /**
     * True if the last open workspace should be reload next time the app if started, false otherwise.
     */
    public final ObservablePreference loadLastWorkspaceOnStartup = booleanPreference("loadLastWorkspaceOnStartup", false);

    /**
     * True to check if a new release is available each time the application starts, false otherwise.
     */
    public final ObservablePreference checkForUpdateOnStartUp = booleanPreference("checkForUpdateOnStartUp", true);

    /**
     * True if the horizontal marker should be displayed on chart views, false otherwise.
     */
    public final ObservablePreference horizontalMarkerOn = booleanPreference("horizontalMarkerOn", false);

    /**
     * True if the vertical marker should be displayed on chart views, false otherwise.
     */
    public final ObservablePreference verticalMarkerOn = booleanPreference("verticalMarkerOn", true);

    /**
     * True if series on area charts should display a brighter coloured outline, false otherwise.
     */
    public final ObservablePreference showOutlineOnAreaCharts = booleanPreference("showOutlineOnAreaCharts", true);

    /**
     * The default opacity value to apply to series on area charts.
     */
    public final ObservablePreference defaultOpacityAreaCharts = doublePreference("defaultOpacityAreaCharts", 0.30d);

    /**
     * True if series on stacked area charts should display a brighter coloured outline, false otherwise.
     */
    public final ObservablePreference showOutlineOnStackedAreaCharts = booleanPreference("showOutlineOnStackedAreaCharts", false);

    /**
     * The default opacity value to apply to series on stacked area charts.
     */
    public final ObservablePreference defaultOpacityStackedAreaCharts = doublePreference("defaultOpacityStackedAreaCharts", 0.70d);

    /**
     * The amount of time notification should over before being automatically dismissed.
     */
    public final ObservablePreference notificationPopupDuration =
            enumPreference(NotificationDurationChoices.class,
                    "notificationPopupDuration",
                    NotificationDurationChoices.TEN_SECONDS);
    /**
     * The location to load plugins from in addition to those on the classpath.
     */
    public final ObservablePreference userPluginsLocation =
            pathPreference("pluginsLocation", Path.of(System.getProperty("user.home")));


    /**
     * True if plugins from the location defined by "pluginsLocation" should be loaded in addition to those
     * on the classpath.
     */
    public final ObservablePreference loadPluginsFromExternalLocation =
            booleanPreference("loadPluginsFromExternalLocation", false);

    /**
     * The line buffer depth for the debug console.
     */
    public final ObservablePreference consoleMaxLineCapacity = integerPreference("consoleMaxLineCapacity", 2000);

    /**
     * True if the vertical maker should span over all stacked charts on a worksheet, false if it should only show
     * over the focused chart.
     */
    public final ObservablePreference fullHeightCrosshairMarker = booleanPreference("fullHeightCrosshairMarker", true);

    /**
     * The maximum number of thread to allocate to the asynchronous tasks thread pool.
     */
    public final ObservablePreference maxAsyncTasksParallelism = integerPreference("maxAsyncTasksParallelism", 4);

    /**
     * The maximum number of thread to allocate to the sub-tasks thread pool.
     */
    public final ObservablePreference maxSubTasksParallelism = integerPreference("maxSubTasksParallelism", 4);

    /**
     * The threading policy used by the async main thread pool.
     */
    public final ObservablePreference asyncThreadPoolPolicy =
            enumPreference(ThreadPoolPolicy.class, "asyncThreadPoolPolicy", ThreadPoolPolicy.WORK_STEALING);

    /**
     * The threading policy used by the sub-tasks thread pool.
     */
    public final ObservablePreference subTasksThreadPoolPolicy =
            enumPreference(ThreadPoolPolicy.class, "subTasksThreadPoolPolicy", ThreadPoolPolicy.WORK_STEALING);

    /**
     * Records the last position of the application window before closing.
     */
    public final ObservablePreference windowLastPosition = objectPreference(Rectangle2D.class,
            "windowLastPosition",
            new Rectangle2D(Double.MAX_VALUE, Double.MAX_VALUE, 0, 0),
            gson::toJson,
            s -> gson.fromJson(s, Rectangle2D.class));

    /**
     * Display a warning if the number of series a user attempts to drop onto a worksheet in a single operation
     * is greater than this value.
     */
    public final ObservablePreference maxSeriesPerChartBeforeWarning =
            integerPreference("maxSeriesPerChartBeforeWarning", 50);

    /**
     * The timeout value in ms for asynchronous tasks (an exception will be thrown past this delay).
     */
    public final ObservablePreference asyncTasksTimeOutMs = longPreference("asyncTasksTimeOutMs", 120000L);

    /**
     * Only trigger treeview filter after this amount of characters have been entered into the text field.
     */
    public final ObservablePreference minCharsTreeFiltering = integerPreference("minCharsTreeFiltering", 1);

    /**
     * True if request pooling on the http client should be enabled, false otherwise.
     */
    public final ObservablePreference httpPoolingEnabled = booleanPreference("httpPoolingEnabled", true);

    /**
     * True if NaN values in series should be replaced by zero before drawing the chart.
     */
    public final ObservablePreference forceNanToZero = booleanPreference("forceNanToZero", true);

    /**
     * True if a heap dump should be generate on out of memory errors, false otherwise.
     */
    public final ObservablePreference heapDumpOnOutOfMemoryError =
            booleanPreference("heapDumpOnOutOfMemoryError", false);

    /**
     * The path where to save heap dumps.
     */
    public final ObservablePreference heapDumpPath =
            pathPreference("heapDumpPath", Path.of(System.getProperty("java.io.tmpdir") + "/binjr"));

    /**
     * The amount of time in ms the pointer must have hovered above a node before a tooltip is shown.
     */
    public final ObservablePreference tooltipShowDelayMs = longPreference("tooltipShowDelayMs", 500L);

    public final ObservablePreference rootLoggingLevel =
            objectPreference(Level.class, "rootLoggingLevel", Level.INFO, Level::name, Level::valueOf);

    public final ObservablePreference redirectStdOutToLogs = booleanPreference("redirectStdOutToLogging", true);

    public final ObservablePreference logFilesLocation =
            pathPreference("logFilesLocation", Path.of(System.getProperty("java.io.tmpdir") + "/binjr"));

    public final ObservablePreference maxLogFilesToKeep = integerPreference("maxLogFilesToKeep", 10);

    public final ObservablePreference persistLogsToFile = booleanPreference("persistLogsToFile", true);

    public final ObservablePreference snapshotOutputScale =
            enumPreference(SnapshotOutputScale.class, "snapshotOutputScale", SnapshotOutputScale.AUTO);

    public final ObservablePreference downSamplingAlgorithm =
            enumPreference(DownSamplingAlgorithm.class, "downSamplingAlgorithm", DownSamplingAlgorithm.AUTO);

    public final ObservablePreference chartColorPalette =
            enumPreference(BuiltInChartColorPalettes.class, "chartColorPalette", BuiltInChartColorPalettes.VIBRANT);

    public final ObservablePreference logFilesColorPalette =
            enumPreference(BuiltInChartColorPalettes.class, "logFilesColorPalette", BuiltInChartColorPalettes.GRAY_SCALE);

    public final ObservablePreference lastCheckForUpdate =
            localDateTimePreference("lastCheckForUpdate", LocalDateTime.MIN);

    public final ObservablePreference searchFieldInputDelayMs = integerPreference("searchFieldInputDelayMs", 600);

    public final ObservablePreference hitsPerPage = integerPreference("hitsPerPage", 10000);

    public final ObservablePreference indexLocation =
            enumPreference(IndexDirectoryLocation.class, "indexLocation", IndexDirectoryLocation.FILES_SYSTEM);

    public final ObservablePreference parsingThreadNumber = integerPreference("parsingThreadNumber", 0);

    public final ObservablePreference blockingQueueCapacity = integerPreference("blockingQueueCapacity", 10000);

    public final ObservablePreference parsingThreadDrainSize = integerPreference("parsingThreadDrainSize", 512);

    public final ObservablePreference preventFoldingAllSourcePanes = booleanPreference("preventFoldingAllSourcePanes", false);

    public final ObservablePreference expandSuggestTreeOnMatch = booleanPreference("expandSuggestTreeOnMatch", false);

    public final ObservablePreference consoleAlwaysOnTop = booleanPreference("consoleAlwaysOnTop", false);

    public final ObservablePreference minChartHeight = doublePreference("minChartHeight", 150.0);

    public final ObservablePreference lowerStackedChartHeight = doublePreference("lowerStackedChartHeight", 80.0);

    public final ObservablePreference lowerOverlaidChartHeight = doublePreference("lowerOverlaidChartHeight", 250.0);

    public final ObservablePreference upperChartHeight = doublePreference("upperChartHeight", 600.0);

    public final ObservablePreference chartZoomFactor = doublePreference("chartZoomFactor", 200.0);

    public final ObservablePreference chartZoomTriggerDelayMs = doublePreference("chartZoomTriggerDelayMs", 500.0);

    public final ObservablePreference logHeatmapNbBuckets = integerPreference("logHeatmapNbBuckets", 150);

    public final ObservablePreference logFilterBarVisible = booleanPreference("logFilterBarVisible", true);

    public final ObservablePreference logFindBarVisible = booleanPreference("logFindBarVisible", false);

    public final ObservablePreference logHeatmapVisible = booleanPreference("logHeatmapVisible", true);

    public final ObservablePreference doNotWarnOnChartClose = booleanPreference("doNotWarnOnChartClose", false);

    public final ObservablePreference doNotWarnOnTabClose = booleanPreference("doNotWarnOnTabClose", false);

    public final ObservablePreference invalidInputColor =
            objectPreference(Color.class, "invalidInputColor", Color.valueOf("0xff646440"), Color::toString, Color::valueOf);

    public final ObservablePreference facetResultCacheEntries = integerPreference("facetResultCacheEntries", 150);

    public final ObservablePreference hitResultCacheMaxSizeMiB = integerPreference("hitResultCacheMaxSizeMiB", 64);

    public final ObservablePreference enableHttpProxy = booleanPreference("enableHttpProxy", false);

    public final ObservablePreference httpProxyHost = stringPreference("httpProxyHost", "");

    public final ObservablePreference httpProxyPort = integerPreference("httpProxyPort", 0);

    public final ObservablePreference useHttpProxyAuth = booleanPreference("useHttpProxyAuth", false);

    public final ObservablePreference httpProxyLogin = stringPreference("httpProxyLogin", "");

    public final ObservablePreference httpProxyPassword = obfuscatedStringPreference("httpProxyPassword", "");

    public ObservablePreference maxSnapshotSnippetHeight = integerPreference("maxSnapshotSnippetHeight", 400);

    public ObservablePreference maxSnapshotSnippetWidth = integerPreference("maxSnapshotSnippetWidth", 300);

    public ObservablePreference httpSocketTimeoutMs = integerPreference("httpSocketTimeoutMs", 30000);

    public ObservablePreference httpConnectionTimeoutMs = integerPreference("httpConnectionTimeoutMs", 30000);

    public ObservablePreference httpResponseTimeoutMs = integerPreference("httpResponseTimeoutMs", 30000);

    public ObservablePreference httpSSLConnectionTTLMs = integerPreference("httpSSLConnectionTTLMs", 120000);

    public ObservablePreference dataAdapterFetchCacheMaxSizeMiB = integerPreference("dataAdapterFetchCacheMaxSizeMiB", 32);

    public ObservablePreference temporaryFilesRoot = pathPreference("temporaryFilesRoot", Path.of(System.getProperty("java.io.tmpdir")));

    public ObservablePreference maxLinesFileTestPreview = integerPreference("maxLinesFileTestPreview", 20);

    /**
     * A list of user defined {@link ParsingProfile} for parsing log events
     */
    public ObservablePreference userLogEventsParsingProfiles =
            objectPreference(ParsingProfile[].class,
                    "userParsingProfiles",
                    new ParsingProfile[0],
                    s -> gson.toJson(s),
                    s -> gson.fromJson(s, CustomParsingProfile[].class)
            );

    public ObservablePreference labelDateFormat = enumPreference(DateFormat.class, "labelDateFormat", DateFormat.RFC_1123);

    public ObservablePreference numIdxMaxPageSize = integerPreference("numIdxMaxPageSize", 200000);

    public ObservablePreference defaultTextViewFontSize = integerPreference("defaultFontSize", 9);

    public ObservablePreference defaultDateTimeAnchor = enumPreference(DateTimeAnchor.class, "defaultDateTimeAnchor", DateTimeAnchor.EPOCH);

    public ObservablePreference alwaysUseEmbeddedFonts = booleanPreference("alwaysUseEmbeddedFonts", false);

    public ObservablePreference logIndexNGramSize = integerPreference("logIndexNGramSize", 2);

    public ObservablePreference logIndexAutoExpendShorterTerms = booleanPreference("logIndexAutoExpendShorterTerms", false);

    public ObservablePreference optimizeNGramQueries = booleanPreference("optimizeNGramQueries", true);

    public ObservablePreference showInlineHelpButtons = booleanPreference("showInlinSHow/eHelpButtons", true);

    public ObservablePreference indexingTokenizer =
            enumPreference(IndexingTokenizer.class, "indexingTokenizer", IndexingTokenizer.NGRAMS);

    public ObservablePreference defaultForceZeroInYAxisAutoRange = booleanPreference("defaultForceZeroInYAxisAutoRange", true);

    public static class UserFavorites extends MruFactory {

        public final MostRecentlyUsedList favoriteLogFilters =
                stringMostRecentlyUsedList("favoriteLogFilters", Integer.MAX_VALUE);

        public UserFavorites(String root) {
            super(root + "/favorites");
        }
    }

    public UserFavorites getFavorites() {
        return favorites;
    }

    @Override
    public void reset() throws BackingStoreException {
        super.reset();
        // Reset adapter preferences
        for (var di : DataAdapterFactory.getInstance().getAllAdapters()) {
            di.getPreferences().reset();
        }
        // Reset user favorites
        favorites.reset();
    }

    @Override
    public void importFromFile(Path savePath) throws IOException, InvalidPreferencesFormatException {
        super.importFromFile(savePath);
        // Reload imported settings to adapter preferences
        for (var di : DataAdapterFactory.getInstance().getAllAdapters()) {
            di.getPreferences().reload();
        }
        // Reload User favorites
        favorites.reload();
    }

    private UserPreferences() {
        super(BINJR_GLOBAL);
    }

    public static UserPreferences getInstance() {
        return UserPreferencesHolder.instance;
    }

    private static class UserPreferencesHolder {
        private final static UserPreferences instance = new UserPreferences();
    }

    private final Map severityStyleMap = Map.ofEntries(
            Map.entry("finer", "trace"),
            Map.entry("finest", "trace"),
            Map.entry("trace", "trace"),
            Map.entry("fine", "debug"),
            Map.entry("debug", "debug"),
            Map.entry("config", "perf"),
            Map.entry("from_cache", "perf"),
            Map.entry("perf", "perf"),
            Map.entry("stdout", "info"),
            Map.entry("ok", "info"),
            Map.entry("info", "info"),
            Map.entry("timeout", "warn"),
            Map.entry("warning", "warn"),
            Map.entry("warn", "warn"),
            Map.entry("severe", "error"),
            Map.entry("stderr", "error"),
            Map.entry("error", "error"),
            Map.entry("fatal", "fatal"));

    public String mapSeverityStyle(String toMap) {
        var style = severityStyleMap.get(toMap.toLowerCase(Locale.ROOT));
        return (style == null) ? "unknown" : style;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy