Skip to content

Commit

Permalink
add verbose logging
Browse files Browse the repository at this point in the history
  • Loading branch information
infeo committed Oct 2, 2024
1 parent 6f3ba44 commit 9e444ec
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 23 deletions.
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/org.cryptomator.jfuse.api.FuseBuilder</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/ch.qos.logback.classic.spi.Configurator</resource>
</transformer>
</transformers>
</configuration>
</execution>
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import ch.qos.logback.classic.spi.Configurator;
import org.cryptomator.cli.LogbackConfigurator;

open module org.cryptomator.cli {
uses Configurator;
requires org.cryptomator.cryptofs;
requires org.cryptomator.frontend.fuse;
requires info.picocli;
requires org.slf4j;
requires org.cryptomator.integrations.api;
requires org.fusesource.jansi;
requires ch.qos.logback.core;
requires ch.qos.logback.classic;

provides Configurator with LogbackConfigurator;
}
13 changes: 13 additions & 0 deletions src/main/java/org/cryptomator/cli/CryptomatorCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public class CryptomatorCli implements Callable<Integer> {
@Parameters(index = "0", paramLabel = "/path/to/vaultDirectory", description = "Path to the vault directory")
Path pathToVault;

@CommandLine.Option(names = {"--verbose"}, description = "Use verbose logging.")
boolean verbose = false;

@CommandLine.ArgGroup(multiplicity = "1")
PasswordSource passwordSource;

Expand All @@ -59,6 +62,15 @@ void setMaxCleartextNameLength(int input) {

@Override
public Integer call() throws Exception {
if (verbose) {
var logConfigurator = LogbackConfigurator.INSTANCE.get();
if (logConfigurator != null) {
logConfigurator.setLogLevels(LogbackConfigurator.DEBUG_LOG_LEVELS);
LOG.debug("User verbose logging");
} else {
throw new IllegalStateException("Logging is not configured.");
}
}
csrpg = SecureRandom.getInstanceStrong();

var unverifiedConfig = readConfigFromStorage(pathToVault);
Expand Down Expand Up @@ -103,6 +115,7 @@ private Masterkey loadMasterkey(URI keyId) {
*/
static VaultConfig.UnverifiedVaultConfig readConfigFromStorage(Path vaultPath) throws IOException {
Path configPath = vaultPath.resolve(CONFIG_FILE_NAME);
LOG.debug("Reading vault config from file {}.", configPath);
String token = Files.readString(configPath, StandardCharsets.US_ASCII);
return VaultConfig.decode(token);
}
Expand Down
77 changes: 77 additions & 0 deletions src/main/java/org/cryptomator/cli/LogbackConfigurator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.cryptomator.cli;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.classic.spi.ConfiguratorRank;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.spi.ContextAwareBase;

import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@ConfiguratorRank(ConfiguratorRank.CUSTOM_HIGH_PRIORITY)
public class LogbackConfigurator extends ContextAwareBase implements Configurator {

public static final AtomicReference<LogbackConfigurator> INSTANCE = new AtomicReference<>();

static final Map<String, Level> DEFAULT_LOG_LEVELS = Map.of( //
Logger.ROOT_LOGGER_NAME, Level.INFO, //
"org.cryptomator", Level.INFO //
);

public static final Map<String, Level> DEBUG_LOG_LEVELS = Map.of( //
Logger.ROOT_LOGGER_NAME, Level.DEBUG, //
"org.cryptomator", Level.TRACE //
);

@Override
public ExecutionStatus configure(LoggerContext context) {
var encoder = new PatternLayoutEncoder();
encoder.setContext(context);
encoder.setPattern("[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n");
encoder.start();

var stdout = new ConsoleAppender<ILoggingEvent>();
stdout.setWithJansi(true);
stdout.setContext(context);
stdout.setName("STDOUT");
stdout.setEncoder(encoder);
stdout.start();

// configure loggers:
for (var loglevel : DEFAULT_LOG_LEVELS.entrySet()) {
Logger logger = context.getLogger(loglevel.getKey());
logger.setLevel(loglevel.getValue());
logger.setAdditive(false);
logger.addAppender(stdout);
}

//disable fuselocking messages
Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks");
fuseLocking.setLevel(Level.OFF);

//make instance accessible
INSTANCE.compareAndSet(null, this);
return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
}

/**
* Adjust the log levels
*
* @param logLevels new log levels to use
*/
public void setLogLevels(Map<String, Level> logLevels) {
if (context instanceof LoggerContext lc) {
for (var loglevel : logLevels.entrySet()) {
Logger logger = lc.getLogger(loglevel.getKey());
System.out.println(logger.getName());
logger.setLevel(loglevel.getValue());
}
}
}

}
50 changes: 41 additions & 9 deletions src/main/java/org/cryptomator/cli/MountOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

import org.cryptomator.integrations.common.IntegrationsLoader;
import org.cryptomator.integrations.mount.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;

import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;

public class MountOptions {

private static final Logger LOG = LoggerFactory.getLogger(MountOptions.class);

@CommandLine.Spec
CommandLine.Model.CommandSpec spec;

Expand Down Expand Up @@ -48,34 +49,65 @@ void setMountService(String value) {
@CommandLine.Option(names = {"--loopbackPort"}, description = "Port used at the loopback address.")
Optional<Integer> loopbackPort;


MountBuilder prepareMountBuilder(FileSystem fs) {
var specifiedOptions = filterNotSpecifiedOptions();
var builder = mountService.forFileSystem(fs.getPath("/"));
for (var capability : mountService.capabilities()) {
switch (capability) {
case FILE_SYSTEM_NAME -> builder.setFileSystemName("cryptoFs");
case LOOPBACK_PORT -> loopbackPort.ifPresent(builder::setLoopbackPort);
case LOOPBACK_HOST_NAME -> loopbackHostName.ifPresent(builder::setLoopbackHostName);
case LOOPBACK_PORT -> {
loopbackPort.ifPresent(builder::setLoopbackPort);
specifiedOptions.put("loopbackPort", false);
}
case LOOPBACK_HOST_NAME -> {
loopbackHostName.ifPresent(builder::setLoopbackHostName);
specifiedOptions.put("loopbackHostname", false);
}
//TODO: case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode.get());
case MOUNT_FLAGS -> {
specifiedOptions.put("mountOptions", false);
if (mountOptions.isEmpty()) {
builder.setMountFlags(mountService.getDefaultMountFlags());
var defaultFlags = mountService.getDefaultMountFlags();
LOG.debug("Using default mount options {}", defaultFlags);
builder.setMountFlags(defaultFlags);
} else {
builder.setMountFlags(String.join(" ", mountOptions));
}
}
case VOLUME_ID -> builder.setVolumeId(volumeId);
case VOLUME_NAME -> volumeName.ifPresent(builder::setVolumeName);
case VOLUME_ID -> {
builder.setVolumeId(volumeId);
}
case VOLUME_NAME -> {
volumeName.ifPresent(builder::setVolumeName);
specifiedOptions.put("volumeName", false);
}
}
}

var ignoredOptions = specifiedOptions.entrySet().stream().filter(Map.Entry::getValue).map(Map.Entry::getKey).collect(Collectors.joining(","));
LOG.info("Ignoring unsupported options: {}", ignoredOptions);
return builder;
}

private Map<String, Boolean> filterNotSpecifiedOptions() {
var map = new HashMap<String, Boolean>();
loopbackPort.ifPresent(_ -> map.put("loopbackPort", true));
loopbackHostName.ifPresent(_ -> map.put("loopbackHostname", true));
volumeName.ifPresent(_ -> map.put("volumeName", true));
if (!mountOptions.isEmpty()) {
map.put("mountOption", true);
}
return map;
}

Mount mount(FileSystem fs) throws MountFailedException {
if (!mountService.hasCapability(MountCapability.MOUNT_TO_SYSTEM_CHOSEN_PATH) && mountPoint.isEmpty()) {
throw new CommandLine.ParameterException(spec.commandLine(), "The selected mounter %s requires a mount point. Use --mountPoint /path/to/mount/point to specify it.".formatted(mountService.displayName()));
}
var builder = prepareMountBuilder(fs);
mountPoint.ifPresent(builder::setMountpoint);
LOG.debug("Mounting vault using {} to {}.", mountService.displayName(), mountPoint.isPresent() ? mountPoint.get() : "system chosen location");
return builder.mount();
}
}
9 changes: 8 additions & 1 deletion src/main/java/org/cryptomator/cli/PasswordSource.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.cryptomator.cli;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;

import java.io.IOException;
Expand All @@ -11,6 +13,8 @@

public class PasswordSource {

public static final Logger LOG = LoggerFactory.getLogger(PasswordSource.class);

@CommandLine.Option(names = {"--password:stdin"}, paramLabel = "Passphrase", description = "Passphrase, read from STDIN")
boolean passphraseStdin;

Expand Down Expand Up @@ -38,6 +42,7 @@ Passphrase readPassphrase() throws IOException {
}

private Passphrase readPassphraseFromStdin() {
LOG.debug("Reading passphrase from STDIN");
System.out.println("Enter the password:");
var console = System.console();
if (console == null) {
Expand All @@ -47,6 +52,7 @@ private Passphrase readPassphraseFromStdin() {
}

private Passphrase readPassphraseFromEnvironment() {
LOG.debug("Reading passphrase from env variable '{}'", passphraseEnvironmentVariable);
var tmp = System.getenv(passphraseEnvironmentVariable);
if (tmp == null) {
throw new ReadingEnvironmentVariableFailedException("Environment variable " + passphraseEnvironmentVariable + " is not defined.");
Expand All @@ -57,6 +63,7 @@ private Passphrase readPassphraseFromEnvironment() {
}

private Passphrase readPassphraseFromFile() throws ReadingFileFailedException {
LOG.debug("Reading passphrase from file '{}'", passphraseFile);
try {
var bytes = Files.readAllBytes(passphraseFile);
var byteBuffer = ByteBuffer.wrap(bytes);
Expand Down Expand Up @@ -90,7 +97,7 @@ static class ReadingEnvironmentVariableFailedException extends PasswordSourceExc
}
}

record Passphrase(char [] content) implements AutoCloseable {
record Passphrase(char[] content) implements AutoCloseable {

@Override
public void close() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.cryptomator.cli.LogbackConfigurator
13 changes: 0 additions & 13 deletions src/main/resources/logback.xml

This file was deleted.

0 comments on commit 9e444ec

Please sign in to comment.