重新实现日志记录 (#2951)

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update
This commit is contained in:
Glavo
2024-03-28 12:16:52 +08:00
committed by GitHub
parent 0b65431044
commit 57018bef47
113 changed files with 864 additions and 632 deletions

View File

@@ -32,9 +32,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvider {
@@ -139,7 +138,7 @@ public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvide
try {
return Optional.of(AuthlibInjectorArtifactInfo.from(path));
} catch (IOException e) {
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
LOG.warning("Bad authlib-injector artifact", e);
return Optional.empty();
}
}

View File

@@ -19,7 +19,7 @@ package org.jackhuang.hmcl.auth.authlibinjector;
import static java.util.Collections.emptyMap;
import static org.jackhuang.hmcl.util.Lang.tryCast;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import java.io.IOException;
import java.lang.reflect.Type;
@@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
import org.jackhuang.hmcl.util.io.HttpRequest;
@@ -254,7 +253,7 @@ public class AuthlibInjectorServer implements Observable {
try {
instance.setMetadataResponse(jsonObj.get("metadataResponse").getAsString(), jsonObj.get("metadataTimestamp").getAsLong());
} catch (JsonParseException e) {
LOG.log(Level.WARNING, "Ignoring malformed metadata response cache: " + jsonObj.get("metadataResponse"), e);
LOG.warning("Ignoring malformed metadata response cache: " + jsonObj.get("metadataResponse"), e);
}
}
return instance;

View File

@@ -17,12 +17,11 @@
*/
package org.jackhuang.hmcl.auth.authlibinjector;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.logging.Level;
public class SimpleAuthlibInjectorArtifactProvider implements AuthlibInjectorArtifactProvider {
@@ -42,7 +41,7 @@ public class SimpleAuthlibInjectorArtifactProvider implements AuthlibInjectorArt
try {
return Optional.of(getArtifactInfo());
} catch (IOException e) {
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
LOG.warning("Bad authlib-injector artifact", e);
return Optional.empty();
}
}

View File

@@ -28,10 +28,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.logging.Level;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class MicrosoftAccount extends OAuthAccount {
@@ -142,7 +141,7 @@ public class MicrosoftAccount extends OAuthAccount {
try {
return YggdrasilService.getTextures(it);
} catch (ServerResponseMalformedException e) {
LOG.log(Level.WARNING, "Failed to parse texture payload", e);
LOG.warning("Failed to parse texture payload", e);
return Optional.empty();
}
}));

View File

@@ -39,13 +39,12 @@ import java.net.URL;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Lang.threadPool;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
public class MicrosoftService {
@@ -62,7 +61,7 @@ public class MicrosoftService {
this.profileRepository = new ObservableOptionalCache<>(uuid -> {
LOG.info("Fetching properties of " + uuid);
return getCompleteGameProfile(uuid);
}, (uuid, e) -> LOG.log(Level.WARNING, "Failed to fetch properties of " + uuid, e), POOL);
}, (uuid, e) -> LOG.warning("Failed to fetch properties of " + uuid, e), POOL);
}
public ObservableOptionalCache<UUID, CompleteGameProfile, AuthenticationException> getProfileRepository() {
@@ -97,7 +96,7 @@ public class MicrosoftService {
}
if (response.displayClaims == null || response.displayClaims.xui == null || response.displayClaims.xui.size() == 0 || !response.displayClaims.xui.get(0).containsKey("uhs")) {
LOG.log(Level.WARNING, "Unrecognized xbox authorization response " + GSON.toJson(response));
LOG.warning("Unrecognized xbox authorization response " + GSON.toJson(response));
throw new NoXuiException();
}

View File

@@ -18,7 +18,7 @@
package org.jackhuang.hmcl.auth.microsoft;
import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.logging.Logger;
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
import java.util.Map;
@@ -45,7 +45,7 @@ public class MicrosoftSession {
this.user = user;
this.profile = profile;
if (accessToken != null) Logging.registerAccessToken(accessToken);
if (accessToken != null) Logger.registerAccessToken(accessToken);
}
public String getTokenType() {

View File

@@ -24,10 +24,9 @@ import org.jackhuang.hmcl.util.javafx.BindingMapping;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.Level;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public abstract class YggdrasilAccount extends ClassicAccount {
@@ -197,7 +196,7 @@ public abstract class YggdrasilAccount extends ClassicAccount {
try {
return YggdrasilService.getTextures(it);
} catch (ServerResponseMalformedException e) {
LOG.log(Level.WARNING, "Failed to parse texture payload", e);
LOG.warning("Failed to parse texture payload", e);
return Optional.empty();
}
}));

View File

@@ -40,13 +40,12 @@ import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.unmodifiableList;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Lang.threadPool;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
public class YggdrasilService {
@@ -63,7 +62,7 @@ public class YggdrasilService {
LOG.info("Fetching properties of " + uuid + " from " + provider);
return getCompleteGameProfile(uuid);
},
(uuid, e) -> LOG.log(Level.WARNING, "Failed to fetch properties of " + uuid + " from " + provider, e),
(uuid, e) -> LOG.warning("Failed to fetch properties of " + uuid + " from " + provider, e),
POOL);
}

View File

@@ -20,7 +20,7 @@ package org.jackhuang.hmcl.auth.yggdrasil;
import com.google.gson.Gson;
import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.logging.Logger;
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +48,7 @@ public class YggdrasilSession {
this.availableProfiles = availableProfiles;
this.userProperties = userProperties;
if (accessToken != null) Logging.registerAccessToken(accessToken);
if (accessToken != null) Logger.registerAccessToken(accessToken);
}
public String getClientToken() {

View File

@@ -36,9 +36,10 @@ import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class DefaultCacheRepository extends CacheRepository {
private Path librariesDir;
private Path indexFile;
@@ -67,7 +68,7 @@ public class DefaultCacheRepository extends CacheRepository {
else
index = new Index();
} catch (IOException | JsonParseException e) {
Logging.LOG.log(Level.WARNING, "Unable to read index file", e);
LOG.warning("Unable to read index file", e);
index = new Index();
} finally {
lock.writeLock().unlock();
@@ -105,7 +106,7 @@ public class DefaultCacheRepository extends CacheRepository {
// or we will not cache the library
}
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + jar, e);
LOG.warning("Unable to calc hash value of file " + jar, e);
}
}
@@ -200,7 +201,7 @@ public class DefaultCacheRepository extends CacheRepository {
try {
FileUtils.writeText(indexFile, JsonUtils.GSON.toJson(index));
} catch (IOException e) {
Logging.LOG.log(Level.SEVERE, "Unable to save index.json", e);
LOG.error("Unable to save index.json", e);
}
}

View File

@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.download;
import org.jackhuang.hmcl.game.*;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.SimpleMultimap;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
@@ -33,11 +32,11 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class MaintainTask extends Task<Version> {
private final GameRepository repository;
@@ -164,7 +163,7 @@ public class MaintainTask extends Task<Version> {
Files.createDirectories(libraryPath.getParent());
Files.copy(input, libraryPath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Unable to unpack HMCLTransformerDiscoveryService", e);
LOG.warning("Unable to unpack HMCLTransformerDiscoveryService", e);
}
});
}

View File

@@ -19,9 +19,8 @@ package org.jackhuang.hmcl.download;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
@@ -71,7 +70,7 @@ public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
return future;
}
LOG.log(Level.WARNING, "Failed to fetch versions list and try to fetch from other source", e);
LOG.warning("Failed to fetch versions list and try to fetch from other source", e);
return refreshAsync(gameVersion, sourceIndex + 1);
}).thenCompose(it -> it);
}

View File

@@ -32,11 +32,10 @@ import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Lang.wrap;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
public final class ForgeBMCLVersionList extends VersionList<ForgeRemoteVersion> {
@@ -104,7 +103,7 @@ public final class ForgeBMCLVersionList extends VersionList<ForgeRemoteVersion>
try {
releaseDate = Instant.parse(version.getModified());
} catch (DateTimeParseException e) {
LOG.log(Level.WARNING, "Failed to parse instant " + version.getModified(), e);
LOG.warning("Failed to parse instant " + version.getModified(), e);
}
}

View File

@@ -60,7 +60,7 @@ import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.gson.JsonUtils.fromNonNullJson;
public class ForgeNewInstallTask extends Task<Version> {

View File

@@ -26,7 +26,6 @@ import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.CacheRepository;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -37,7 +36,8 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
@@ -100,7 +100,7 @@ public final class GameAssetDownloadTask extends Task<Void> {
if (!download && integrityCheck && !assetObject.validateChecksum(file, true))
download = true;
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + file, e);
LOG.warning("Unable to calc hash value of file " + file, e);
}
if (download) {
List<URL> urls = dependencyManager.getDownloadProvider().getAssetObjectCandidates(assetObject.getLocation());

View File

@@ -34,9 +34,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* This task is to download asset index file provided in minecraft.json.
@@ -82,7 +81,7 @@ public final class GameAssetIndexDownloadTask extends Task<Void> {
if (actualSum.equalsIgnoreCase(assetIndexInfo.getSha1()))
return;
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to calculate sha1sum of file " + assetIndexInfo, e);
LOG.warning("Failed to calculate sha1sum of file " + assetIndexInfo, e);
// continue downloading
}
} else {

View File

@@ -23,7 +23,6 @@ import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
@@ -31,7 +30,8 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* This task is to download game libraries.
@@ -98,7 +98,7 @@ public final class GameLibrariesTask extends Task<Void> {
}
}
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + jar, e);
LOG.warning("Unable to calc hash value of file " + jar, e);
}
return false;

View File

@@ -39,9 +39,8 @@ import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class LibraryDownloadTask extends Task<Void> {
private FileDownloadTask task;
@@ -111,7 +110,7 @@ public class LibraryDownloadTask extends Task<Void> {
cached = true;
return;
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to copy file from cache", e);
LOG.warning("Failed to copy file from cache", e);
// We cannot copy cached file to current location
// so we try to download a new one.
}
@@ -137,7 +136,7 @@ public class LibraryDownloadTask extends Task<Void> {
try {
cacheRepository.cacheLibrary(library, jar.toPath(), false);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to cache downloaded library " + library, e);
LOG.warning("Failed to cache downloaded library " + library, e);
}
}
}

View File

@@ -42,7 +42,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class JavaDownloadTask extends Task<Void> {
private final GameJavaVersion javaVersion;

View File

@@ -17,10 +17,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class JavaRepository {
private JavaRepository() {
@@ -80,7 +79,7 @@ public final class JavaRepository {
findJavaHomeInComponentDir(platform, component).ifPresent(javaHomes::add);
}
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to list java-runtime directory " + runtimeDir, e);
LOG.warning("Failed to list java-runtime directory " + runtimeDir, e);
}
};
getSystemJavaPlatform().ifPresent(action);
@@ -124,7 +123,7 @@ public final class JavaRepository {
return Optional.of(dir);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to verify Java in " + component, e);
LOG.warning("Failed to verify Java in " + component, e);
return Optional.empty();
}
}

View File

@@ -56,7 +56,7 @@ import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.gson.JsonUtils.fromNonNullJson;
public class NeoForgeOldInstallTask extends Task<Version> {

View File

@@ -17,10 +17,10 @@
*/
package org.jackhuang.hmcl.event;
import org.jackhuang.hmcl.util.Logging;
import java.util.concurrent.ConcurrentHashMap;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
* @author huangyuhui
@@ -36,7 +36,7 @@ public final class EventBus {
@SuppressWarnings("unchecked")
public Event.Result fireEvent(Event obj) {
Logging.LOG.info(obj + " gets fired");
LOG.info(obj + " gets fired");
return channel((Class<Event>) obj.getClass()).fireEvent(obj);
}

View File

@@ -53,10 +53,9 @@ import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* An implementation of classic Minecraft game repository.
@@ -232,7 +231,7 @@ public class DefaultGameRepository implements GameRepository {
}
return true;
} catch (IOException | JsonParseException | VersionNotFoundException | InvalidPathException e) {
LOG.log(Level.WARNING, "Unable to rename version " + from + " to " + to, e);
LOG.warning("Unable to rename version " + from + " to " + to, e);
return false;
}
}
@@ -267,7 +266,7 @@ public class DefaultGameRepository implements GameRepository {
try {
FileUtils.deleteDirectory(removedFile);
} catch (IOException e) {
LOG.log(Level.WARNING, "Unable to remove version folder: " + file, e);
LOG.warning("Unable to remove version folder: " + file, e);
}
return true;
} finally {
@@ -317,7 +316,7 @@ public class DefaultGameRepository implements GameRepository {
try {
version = readVersionJson(json);
} catch (Exception e) {
LOG.log(Level.WARNING, "Malformed version json " + id, e);
LOG.warning("Malformed version json " + id, e);
// JsonSyntaxException or IOException or NullPointerException(!!)
if (EventBus.EVENT_BUS.fireEvent(new GameJsonParseFailedEvent(this, json, id)) != Event.Result.ALLOW)
return Stream.empty();
@@ -325,7 +324,7 @@ public class DefaultGameRepository implements GameRepository {
try {
version = readVersionJson(json);
} catch (Exception e2) {
LOG.log(Level.SEVERE, "User corrected version json is still malformed", e2);
LOG.error("User corrected version json is still malformed", e2);
return Stream.empty();
}
}
@@ -355,7 +354,7 @@ public class DefaultGameRepository implements GameRepository {
throw e;
}
} catch (IOException e) {
LOG.log(Level.WARNING, "Ignoring version " + version.getId() + " because version id does not match folder name " + id + ", and we cannot correct it.", e);
LOG.warning("Ignoring version " + version.getId() + " because version id does not match folder name " + id + ", and we cannot correct it.", e);
return Stream.empty();
}
}
@@ -371,7 +370,7 @@ public class DefaultGameRepository implements GameRepository {
EventBus.EVENT_BUS.fireEvent(new LoadedOneVersionEvent(this, resolved)) != Event.Result.DENY)
versions.put(version.getId(), version);
} catch (VersionNotFoundException e) {
LOG.log(Level.WARNING, "Ignoring version " + version.getId() + " because it inherits from a nonexistent version.");
LOG.warning("Ignoring version " + version.getId() + " because it inherits from a nonexistent version.");
}
}
@@ -402,7 +401,7 @@ public class DefaultGameRepository implements GameRepository {
try {
return reconstructAssets(version, assetId);
} catch (IOException | JsonParseException e) {
LOG.log(Level.SEVERE, "Unable to reconstruct asset directory", e);
LOG.error("Unable to reconstruct asset directory", e);
return getAssetDirectory(version, assetId);
}
}

View File

@@ -20,7 +20,7 @@ package org.jackhuang.hmcl.game;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.logging.Logger;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
@@ -28,9 +28,8 @@ import java.io.*;
import java.nio.CharBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Generate a JVM dump on a process.
@@ -78,7 +77,7 @@ public final class GameDumpGenerator {
execute(vm, "VM.command_line", stringBuilder);
writeDumpHeadKeyValueTo(
"VM Command Line",
Logging.filterForbiddenToken(stringBuilder.toString()),
Logger.filterForbiddenToken(stringBuilder.toString()),
writer,
true
);
@@ -137,7 +136,7 @@ public final class GameDumpGenerator {
try {
return VirtualMachine.attach(lvmid);
} catch (Throwable e) {
LOG.log(Level.WARNING, "An exception encountered while attaching vm " + lvmid, e);
LOG.warning("An exception encountered while attaching vm " + lvmid, e);
writer.write(StringUtils.getStackTrace(e));
writer.write('\n');
Thread.sleep(3000);
@@ -158,7 +157,7 @@ public final class GameDumpGenerator {
target.append(cb, 0, len);
}
} catch (Throwable throwable) {
LOG.log(Level.WARNING, "An exception encountered while executing jcmd " + vm.id(), throwable);
LOG.warning("An exception encountered while executing jcmd " + vm.id(), throwable);
target.append(StringUtils.getStackTrace(throwable));
target.append('\n');
}

View File

@@ -30,14 +30,13 @@ import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.jackhuang.hmcl.util.Lang.tryCast;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* @author huangyuhui
@@ -51,7 +50,7 @@ final class GameVersion {
Map<?, ?> version = JsonUtils.fromNonNullJsonFully(versionJson, Map.class);
return tryCast(version.get("id"), String.class);
} catch (IOException | JsonParseException e) {
LOG.log(Level.WARNING, "Failed to parse version.json", e);
LOG.warning("Failed to parse version.json", e);
return Optional.empty();
}
}

View File

@@ -21,7 +21,6 @@ import com.google.gson.JsonParseException;
import org.jackhuang.hmcl.util.Constants;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.ToStringBuilder;
import org.jackhuang.hmcl.util.gson.JsonMap;
@@ -38,9 +37,10 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
* @author huangyuhui
@@ -287,7 +287,7 @@ public class Version implements Comparable<Version>, Validation {
} else {
// To maximize the compatibility.
if (!resolvedSoFar.add(id)) {
Logging.LOG.log(Level.WARNING, "Found circular dependency versions: " + resolvedSoFar);
LOG.warning("Found circular dependency versions: " + resolvedSoFar);
thisVersion = this.jar == null ? this.setJar(id) : this;
} else {
// It is supposed to auto install an version in getVersion.
@@ -331,7 +331,7 @@ public class Version implements Comparable<Version>, Validation {
} else {
// To maximize the compatibility.
if (!resolvedSoFar.add(id)) {
Logging.LOG.log(Level.WARNING, "Found circular dependency versions: " + resolvedSoFar);
LOG.warning("Found circular dependency versions: " + resolvedSoFar);
// keep thisVersion
} else {
// It is supposed to auto install an version in getVersion.

View File

@@ -22,7 +22,6 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.Unzipper;
@@ -33,12 +32,13 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.*;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class World {
private final Path file;
@@ -237,13 +237,13 @@ public class World {
try {
return Stream.of(new World(world));
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to read world " + world, e);
LOG.warning("Failed to read world " + world, e);
return Stream.empty();
}
});
}
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to read saves", e);
LOG.warning("Failed to read saves", e);
}
return Stream.empty();
}

View File

@@ -40,10 +40,9 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Supplier;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
/**
@@ -147,7 +146,7 @@ public class DefaultLauncher extends Launcher {
try {
encoding = Charset.forName(fileEncoding.substring("-Dfile.encoding=".length()));
} catch (Throwable ex) {
LOG.log(Level.WARNING, "Bad file encoding", ex);
LOG.warning("Bad file encoding", ex);
}
}
@@ -705,7 +704,7 @@ public class DefaultLauncher extends Launcher {
builder.environment().putAll(getEnvVars());
SystemUtils.callExternalProcess(builder);
} catch (Throwable e) {
LOG.log(Level.WARNING, "An Exception happened while running exit command.", e);
LOG.warning("An Exception happened while running exit command.", e);
}
}
}), "exit-waiter", isDaemon));

View File

@@ -17,8 +17,6 @@
*/
package org.jackhuang.hmcl.launch;
import org.jackhuang.hmcl.util.Logging;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -26,7 +24,8 @@ import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Pump the given input stream.
@@ -68,7 +67,7 @@ public final class StreamPump implements Runnable {
callback.accept(line);
}
} catch (IOException e) {
Logging.LOG.log(Level.SEVERE, "An error occurred when reading stream", e);
LOG.error("An error occurred when reading stream", e);
}
}

View File

@@ -24,7 +24,6 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.jackhuang.hmcl.mod.modinfo.PackMcMeta;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils;
@@ -34,7 +33,8 @@ import org.jackhuang.hmcl.util.io.Unzipper;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class Datapack {
private boolean isMultiple;
@@ -133,7 +133,7 @@ public class Datapack {
PackMcMeta pack = JsonUtils.fromNonNullJson(FileUtils.readText(mcmeta), PackMcMeta.class);
Platform.runLater(() -> info.add(new Pack(path, FileUtils.getNameWithoutExtension(path), pack.getPackInfo().getDescription(), this)));
} catch (IOException | JsonParseException e) {
Logging.LOG.log(Level.WARNING, "Failed to read datapack " + path, e);
LOG.warning("Failed to read datapack " + path, e);
}
} else {
throw new IOException("Malformed datapack zip");
@@ -145,7 +145,7 @@ public class Datapack {
try {
loadFromDir(path);
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to read datapacks " + path, e);
LOG.warning("Failed to read datapacks " + path, e);
}
}
@@ -169,7 +169,7 @@ public class Datapack {
: JsonUtils.fromNonNullJson(FileUtils.readText(mcmetaDisabled), PackMcMeta.class);
info.add(new Pack(enabled ? mcmeta : mcmetaDisabled, FileUtils.getName(subDir), pack.getPackInfo().getDescription(), this));
} catch (IOException | JsonParseException e) {
Logging.LOG.log(Level.WARNING, "Failed to read datapack " + subDir, e);
LOG.warning("Failed to read datapack " + subDir, e);
}
} else if (Files.isRegularFile(subDir)) {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(subDir)) {
@@ -189,7 +189,7 @@ public class Datapack {
PackMcMeta pack = JsonUtils.fromNonNullJson(FileUtils.readText(mcmeta), PackMcMeta.class);
info.add(new Pack(subDir, name, pack.getPackInfo().getDescription(), this));
} catch (IOException | JsonParseException e) {
Logging.LOG.log(Level.WARNING, "Failed to read datapack " + subDir, e);
LOG.warning("Failed to read datapack " + subDir, e);
}
}
}
@@ -226,7 +226,7 @@ public class Datapack {
Pack.this.file = newF;
} catch (IOException e) {
// Mod file is occupied.
Logging.LOG.warning("Unable to rename file " + f + " to " + newF);
LOG.warning("Unable to rename file " + f + " to " + newF);
}
}
};

View File

@@ -19,15 +19,15 @@ package org.jackhuang.hmcl.mod;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
* @author huangyuhui
@@ -76,7 +76,7 @@ public final class LocalModFile implements Comparable<LocalModFile> {
else
LocalModFile.this.file = modManager.disableMod(path);
} catch (IOException e) {
Logging.LOG.log(Level.SEVERE, "Unable to invert state of mod file " + path, e);
LOG.error("Unable to invert state of mod file " + path, e);
}
}
};

View File

@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.mod.ModpackCompletionException;
import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -37,10 +36,11 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Complete the CurseForge version.
*
@@ -89,7 +89,7 @@ public final class CurseCompletionTask extends Task<Void> {
if (manifestFile.exists())
this.manifest = JsonUtils.GSON.fromJson(FileUtils.readText(manifestFile), CurseManifest.class);
} catch (Exception e) {
Logging.LOG.log(Level.WARNING, "Unable to read CurseForge modpack manifest.json", e);
LOG.warning("Unable to read CurseForge modpack manifest.json", e);
}
setStage("hmcl.modpack.download");
@@ -123,11 +123,11 @@ public final class CurseCompletionTask extends Task<Void> {
RemoteMod.File remoteFile = CurseForgeRemoteModRepository.MODS.getModFile(Integer.toString(file.getProjectID()), Integer.toString(file.getFileID()));
return file.withFileName(remoteFile.getFilename()).withURL(remoteFile.getUrl());
} catch (FileNotFoundException fof) {
Logging.LOG.log(Level.WARNING, "Could not query api.curseforge.com for deleted mods: " + file.getProjectID() + ", " + file.getFileID(), fof);
LOG.warning("Could not query api.curseforge.com for deleted mods: " + file.getProjectID() + ", " + file.getFileID(), fof);
notFound.set(true);
return file;
} catch (IOException | JsonParseException e) {
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name projectID=" + file.getProjectID() + ", fileID=" + file.getFileID(), e);
LOG.warning("Unable to fetch the file name projectID=" + file.getProjectID() + ", fileID=" + file.getFileID(), e);
allNameKnown.set(false);
return file;
}
@@ -156,7 +156,7 @@ public final class CurseCompletionTask extends Task<Void> {
task.setCaching(true);
return Stream.of(task.withCounter("hmcl.modpack.download"));
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Could not query api.curseforge.com for mod: " + f.getProjectID() + ", " + f.getFileID(), e);
LOG.warning("Could not query api.curseforge.com for mod: " + f.getProjectID() + ", " + f.getFileID(), e);
return Stream.empty(); // Ignore this file.
} finally {
updateProgress(finished.incrementAndGet(), newManifest.getFiles().size());

View File

@@ -27,7 +27,6 @@ import org.jackhuang.hmcl.mod.ModpackCompletionException;
import org.jackhuang.hmcl.mod.curse.CurseMetaMod;
import org.jackhuang.hmcl.task.*;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -46,12 +45,12 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.Lang.wrap;
import static org.jackhuang.hmcl.util.Lang.wrapConsumer;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
@@ -211,7 +210,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
CurseMetaMod mod = JsonUtils.fromNonNullJson(result, CurseMetaMod.class);
return file.withFileName(mod.getFileNameOnDisk()).withURL(mod.getDownloadURL());
} catch (FileNotFoundException fof) {
Logging.LOG.log(Level.WARNING, "Could not query cursemeta for deleted mods: " + file.getUrl(), fof);
LOG.warning("Could not query cursemeta for deleted mods: " + file.getUrl(), fof);
notFound.set(true);
return file;
} catch (IOException | JsonParseException e2) {
@@ -220,13 +219,13 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
CurseMetaMod mod = JsonUtils.fromNonNullJson(result, CurseMetaMod.class);
return file.withFileName(mod.getFileName()).withURL(mod.getDownloadURL());
} catch (FileNotFoundException fof) {
Logging.LOG.log(Level.WARNING, "Could not query forgesvc for deleted mods: " + file.getUrl(), fof);
LOG.warning("Could not query forgesvc for deleted mods: " + file.getUrl(), fof);
notFound.set(true);
return file;
} catch (IOException | JsonParseException e3) {
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name of URL: " + file.getUrl(), e);
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name of URL: " + file.getUrl(), e2);
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name of URL: " + file.getUrl(), e3);
LOG.warning("Unable to fetch the file name of URL: " + file.getUrl(), e);
LOG.warning("Unable to fetch the file name of URL: " + file.getUrl(), e2);
LOG.warning("Unable to fetch the file name of URL: " + file.getUrl(), e3);
allNameKnown.set(false);
return file;
}

View File

@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.mod.curse.CurseManifestMinecraft;
import org.jackhuang.hmcl.mod.curse.CurseManifestModLoader;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.Zipper;
@@ -42,6 +41,7 @@ import java.util.Collections;
import java.util.List;
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class McbbsModpackExportTask extends Task<Void> {
private final DefaultGameRepository repository;
@@ -65,7 +65,7 @@ public class McbbsModpackExportTask extends Task<Void> {
ArrayList<String> blackList = new ArrayList<>(ModAdviser.MODPACK_BLACK_LIST);
blackList.add(version + ".jar");
blackList.add(version + ".json");
Logging.LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(modpackFile.toPath())) {
Path runDirectory = repository.getRunDirectory(version).toPath();
List<McbbsModpackManifest.File> files = new ArrayList<>();

View File

@@ -17,9 +17,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
@Immutable
public final class ForgeNewModMetadata {
@@ -129,7 +128,7 @@ public final class ForgeNewModMetadata {
Manifest manifest = new Manifest(is);
jarVersion = manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to parse MANIFEST.MF in file " + modFile);
LOG.warning("Failed to parse MANIFEST.MF in file " + modFile);
}
}

View File

@@ -22,7 +22,6 @@ import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.mod.ModpackCompletionException;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -35,7 +34,8 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class ModrinthCompletionTask extends Task<Void> {
@@ -78,7 +78,7 @@ public class ModrinthCompletionTask extends Task<Void> {
if (manifestFile.exists())
this.manifest = JsonUtils.GSON.fromJson(FileUtils.readText(manifestFile), ModrinthManifest.class);
} catch (Exception e) {
Logging.LOG.log(Level.WARNING, "Unable to read Modrinth modpack manifest.json", e);
LOG.warning("Unable to read Modrinth modpack manifest.json", e);
}
setStage("hmcl.modpack.download");

View File

@@ -23,7 +23,6 @@ import org.jackhuang.hmcl.mod.ModAdviser;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackExportInfo;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.Zipper;
@@ -34,6 +33,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Export the game to a mod pack file.
@@ -66,7 +66,7 @@ public class MultiMCModpackExportTask extends Task<Void> {
ArrayList<String> blackList = new ArrayList<>(ModAdviser.MODPACK_BLACK_LIST);
blackList.add(versionId + ".jar");
blackList.add(versionId + ".json");
Logging.LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(output.toPath())) {
zip.putDirectory(repository.getRunDirectory(versionId).toPath(), ".minecraft", path -> Modpack.acceptFile(path, blackList, whitelist));

View File

@@ -27,7 +27,6 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.GetTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -40,9 +39,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class ServerModpackCompletionTask extends Task<Void> {
private final DefaultDependencyManager dependencyManager;
@@ -70,7 +70,7 @@ public class ServerModpackCompletionTask extends Task<Void> {
}.getType());
}
} catch (Exception e) {
Logging.LOG.log(Level.WARNING, "Unable to read Server modpack manifest.json", e);
LOG.warning("Unable to read Server modpack manifest.json", e);
}
} else {
this.manifest = manifest;

View File

@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.mod.ModpackConfiguration;
import org.jackhuang.hmcl.mod.ModpackExportInfo;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.Zipper;
@@ -38,6 +37,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class ServerModpackExportTask extends Task<Void> {
private final DefaultGameRepository repository;
@@ -61,7 +61,7 @@ public class ServerModpackExportTask extends Task<Void> {
ArrayList<String> blackList = new ArrayList<>(ModAdviser.MODPACK_BLACK_LIST);
blackList.add(versionId + ".jar");
blackList.add(versionId + ".json");
Logging.LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(modpackFile.toPath())) {
Path runDirectory = repository.getRunDirectory(versionId).toPath();
List<ModpackConfiguration.FileInformation> files = new ArrayList<>();

View File

@@ -19,14 +19,13 @@ package org.jackhuang.hmcl.task;
import com.google.gson.JsonParseException;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.Logging;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.*;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Lang.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
@@ -49,7 +48,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
if (!success) {
// We log exception stacktrace because some of exceptions occurred because of bugs.
Logging.LOG.log(Level.WARNING, "An exception occurred in task execution", exception);
LOG.warning("An exception occurred in task execution", exception);
Throwable resolvedException = resolveException(exception);
if (resolvedException instanceof RuntimeException &&
@@ -82,7 +81,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
} catch (ExecutionException ignore) {
// We have dealt with ExecutionException in exception handling and uncaught exception handler.
} catch (CancellationException e) {
Logging.LOG.log(Level.INFO, "Task " + firstTask + " has been cancelled.", e);
LOG.info("Task " + firstTask + " has been cancelled.", e);
}
return false;
}
@@ -141,7 +140,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
task.setStage(parentTask.getStage());
if (task.getSignificance().shouldLog())
Logging.LOG.log(Level.FINE, "Executing task: " + task.getName());
LOG.trace("Executing task: " + task.getName());
taskListeners.forEach(it -> it.onReady(task));
@@ -161,7 +160,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
checkCancellation();
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINER, "Task finished: " + task.getName());
LOG.trace("Task finished: " + task.getName());
}
task.setResult(result);
@@ -179,7 +178,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
if (e instanceof InterruptedException || e instanceof CancellationException) {
task.setException(null);
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINE, "Task aborted: " + task.getName());
LOG.trace("Task aborted: " + task.getName());
}
task.onDone().fireEvent(new TaskEvent(this, task, true));
taskListeners.forEach(it -> it.onFailed(task, e));
@@ -187,7 +186,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
task.setException(e);
exception = e;
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINE, "Task failed: " + task.getName(), e);
LOG.trace("Task failed: " + task.getName(), e);
}
task.onDone().fireEvent(new TaskEvent(this, task, true));
taskListeners.forEach(it -> it.onFailed(task, e));
@@ -215,7 +214,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
task.setNotifyPropertiesChanged(() -> taskListeners.forEach(it -> it.onPropertiesUpdate(task)));
if (task.getSignificance().shouldLog())
Logging.LOG.log(Level.FINE, "Executing task: " + task.getName());
LOG.trace("Executing task: " + task.getName());
taskListeners.forEach(it -> it.onReady(task));
@@ -266,7 +265,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
boolean isDependenciesSucceeded = dependenciesException == null;
if (!isDependenciesSucceeded) {
Logging.LOG.severe("Subtasks failed for " + task.getName());
LOG.error("Subtasks failed for " + task.getName());
task.setException(dependenciesException);
if (task.isRelyingOnDependencies()) {
rethrow(dependenciesException);
@@ -276,7 +275,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
checkCancellation();
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINER, "Task finished: " + task.getName());
LOG.trace("Task finished: " + task.getName());
}
task.onDone().fireEvent(new TaskEvent(this, task, false));
@@ -294,11 +293,11 @@ public final class AsyncTaskExecutor extends TaskExecutor {
exception = e;
if (e instanceof CancellationException) {
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINE, "Task aborted: " + task.getName());
LOG.trace("Task aborted: " + task.getName());
}
} else {
if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINE, "Task failed: " + task.getName(), e);
LOG.trace("Task failed: " + task.getName(), e);
}
}
task.onDone().fireEvent(new TaskEvent(this, task, true));

View File

@@ -20,7 +20,6 @@ package org.jackhuang.hmcl.task;
import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.event.EventBus;
import org.jackhuang.hmcl.util.CacheRepository;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.ToStringBuilder;
import org.jackhuang.hmcl.util.io.IOUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
@@ -37,10 +36,10 @@ import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.Lang.threadPool;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public abstract class FetchTask<T> extends Task<T> {
protected final List<URL> urls;
@@ -116,7 +115,7 @@ public abstract class FetchTask<T> extends Task<T> {
useCachedResult(cache);
return;
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Unable to use cached file, redownload " + url, e);
LOG.warning("Unable to use cached file, redownload " + url, e);
repository.removeRemoteEntry(conn);
// Now we must reconnect the server since 304 may result in empty content,
// if we want to redownload the file, we must reconnect the server without etag settings.
@@ -167,13 +166,13 @@ public abstract class FetchTask<T> extends Task<T> {
} catch (FileNotFoundException ex) {
failedURL = url;
exception = ex;
Logging.LOG.log(Level.WARNING, "Failed to download " + url + ", not found" + ((redirects == null || redirects.isEmpty()) ? "" : ", redirects: " + redirects), ex);
LOG.warning("Failed to download " + url + ", not found" + ((redirects == null || redirects.isEmpty()) ? "" : ", redirects: " + redirects), ex);
break; // we will not try this URL again
} catch (IOException ex) {
failedURL = url;
exception = ex;
Logging.LOG.log(Level.WARNING, "Failed to download " + url + ", repeat times: " + (++repeat) + ((redirects == null || redirects.isEmpty()) ? "" : ", redirects: " + redirects), ex);
LOG.warning("Failed to download " + url + ", repeat times: " + (++repeat) + ((redirects == null || redirects.isEmpty()) ? "" : ", redirects: " + redirects), ex);
}
}
}

View File

@@ -18,7 +18,6 @@
package org.jackhuang.hmcl.task;
import org.jackhuang.hmcl.util.Hex;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -33,10 +32,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.*;
import java.util.logging.Level;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.DigestUtils.getDigest;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* A task that can download a file online.
@@ -166,10 +165,10 @@ public class FileDownloadTask extends FetchTask<Void> {
if (cache.isPresent()) {
try {
FileUtils.copyFile(cache.get().toFile(), file);
Logging.LOG.log(Level.FINER, "Successfully verified file " + file + " from " + urls.get(0));
LOG.trace("Successfully verified file " + file + " from " + urls.get(0));
return EnumCheckETag.CACHED;
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to copy cache files", e);
LOG.warning("Failed to copy cache files", e);
}
}
return EnumCheckETag.NOT_CHECK_E_TAG;
@@ -180,7 +179,7 @@ public class FileDownloadTask extends FetchTask<Void> {
@Override
protected void beforeDownload(URL url) {
Logging.LOG.log(Level.FINER, "Downloading " + url + " to " + file);
LOG.trace("Downloading " + url + " to " + file);
}
@Override
@@ -209,14 +208,14 @@ public class FileDownloadTask extends FetchTask<Void> {
try {
rFile.close();
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to close file: " + rFile, e);
LOG.warning("Failed to close file: " + rFile, e);
}
if (!isSuccess()) {
try {
Files.delete(temp);
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to delete file: " + rFile, e);
LOG.warning("Failed to delete file: " + rFile, e);
}
return;
}
@@ -244,7 +243,7 @@ public class FileDownloadTask extends FetchTask<Void> {
try {
repository.cacheFile(file.toPath(), integrityCheck.getAlgorithm(), integrityCheck.getChecksum());
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to cache file", e);
LOG.warning("Failed to cache file", e);
}
}

View File

@@ -18,11 +18,11 @@
package org.jackhuang.hmcl.task;
import javafx.application.Platform;
import org.jackhuang.hmcl.util.Logging;
import java.util.concurrent.*;
import static org.jackhuang.hmcl.util.Lang.threadPool;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
@@ -65,7 +65,7 @@ public final class Schedulers {
}
public static synchronized void shutdown() {
Logging.LOG.info("Shutting down executor services.");
LOG.info("Shutting down executor services.");
// shutdownNow will interrupt all threads.
// So when we want to close the app, no threads need to be waited for finish.

View File

@@ -24,7 +24,6 @@ import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import org.jackhuang.hmcl.event.EventManager;
import org.jackhuang.hmcl.util.InvocationDispatcher;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.ReflectionHelper;
import org.jackhuang.hmcl.util.function.ExceptionalConsumer;
import org.jackhuang.hmcl.util.function.ExceptionalFunction;
@@ -39,9 +38,10 @@ import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Disposable task.
*
@@ -359,7 +359,7 @@ public abstract class Task<T> {
public final T run() throws Exception {
if (getSignificance().shouldLog())
Logging.LOG.log(Level.FINE, "Executing task: " + getName());
LOG.trace("Executing task: " + getName());
for (Task<?> task : getDependents())
doSubTask(task);
@@ -776,7 +776,7 @@ public abstract class Task<T> {
try {
success.run();
} catch (Exception e) {
Logging.LOG.log(Level.WARNING, "Failed to execute " + success, e);
LOG.warning("Failed to execute " + success, e);
if (failure != null)
failure.accept(e);
}

View File

@@ -43,11 +43,10 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction;
import java.util.logging.Level;
import java.util.stream.Stream;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class CacheRepository {
private Path commonDirectory;
@@ -77,7 +76,7 @@ public class CacheRepository {
} else
index = new HashMap<>();
} catch (IOException | JsonParseException e) {
LOG.log(Level.WARNING, "Unable to read index file", e);
LOG.warning("Unable to read index file", e);
index = new HashMap<>();
} finally {
lock.writeLock().unlock();
@@ -263,7 +262,7 @@ public class CacheRepository {
try {
Files.deleteIfExists(cached);
} catch (IOException e) {
LOG.log(Level.WARNING, "Cannot delete old file");
LOG.warning("Cannot delete old file");
}
return newItem;
} else {
@@ -417,7 +416,7 @@ public class CacheRepository {
}.getType()));
}
} catch (IOException | JsonParseException e) {
LOG.log(Level.WARNING, "Unable to read storage {" + name + "} file");
LOG.warning("Unable to read storage {" + name + "} file");
} finally {
lock.writeLock().unlock();
}
@@ -438,7 +437,7 @@ public class CacheRepository {
lock.release();
}
} catch (IOException e) {
LOG.log(Level.WARNING, "Unable to write storage {" + name + "} file");
LOG.warning("Unable to write storage {" + name + "} file");
}
}
}

View File

@@ -1,165 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util;
import org.jackhuang.hmcl.util.io.IOUtils;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.logging.*;
/**
* @author huangyuhui
*/
public final class Logging {
private Logging() {
}
public static final Logger LOG = Logger.getLogger("HMCL");
private static final ByteArrayOutputStream storedLogs = new ByteArrayOutputStream(IOUtils.DEFAULT_BUFFER_SIZE);
private static volatile String[] accessTokens = new String[0];
public static synchronized void registerAccessToken(String token) {
final String[] oldAccessTokens = accessTokens;
final String[] newAccessTokens = Arrays.copyOf(oldAccessTokens, oldAccessTokens.length + 1);
newAccessTokens[oldAccessTokens.length] = token;
accessTokens = newAccessTokens;
}
public static String filterForbiddenToken(String message) {
for (String token : accessTokens)
message = message.replace(token, "<access token>");
return message;
}
public static void start(Path logFolder) {
LOG.setLevel(Level.ALL);
LOG.setUseParentHandlers(false);
LOG.setFilter(record -> {
record.setMessage(format(record));
return true;
});
DefaultFormatter formatter = new DefaultFormatter();
try {
if (Files.isRegularFile(logFolder))
Files.delete(logFolder);
Files.createDirectories(logFolder);
FileHandler fileHandler = new FileHandler(logFolder.resolve("hmcl.log").toAbsolutePath().toString());
fileHandler.setLevel(Level.FINEST);
fileHandler.setFormatter(formatter);
fileHandler.setEncoding("UTF-8");
LOG.addHandler(fileHandler);
} catch (IOException e) {
System.err.println("Unable to create hmcl.log\n" + StringUtils.getStackTrace(e));
}
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
consoleHandler.setLevel(Level.FINER);
LOG.addHandler(consoleHandler);
StreamHandler streamHandler = new StreamHandler(storedLogs, formatter) {
@Override
public synchronized void publish(LogRecord record) {
super.publish(record);
flush();
}
};
try {
streamHandler.setEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
streamHandler.setLevel(Level.ALL);
LOG.addHandler(streamHandler);
}
public static void initForTest() {
LOG.setLevel(Level.ALL);
LOG.setUseParentHandlers(false);
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(new DefaultFormatter());
consoleHandler.setLevel(Level.FINER);
LOG.addHandler(consoleHandler);
}
public static byte[] getRawLogs() {
return storedLogs.toByteArray();
}
public static String getLogs() {
try {
return storedLogs.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalError(e);
}
}
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss").withZone(ZoneId.systemDefault());
private static String format(LogRecord record) {
String message = filterForbiddenToken(record.getMessage());
StringBuilder builder = new StringBuilder(128 + message.length());
builder.append('[');
TIME_FORMATTER.formatTo(Instant.ofEpochMilli(record.getMillis()), builder);
builder.append(']');
builder.append(" [")
.append(record.getSourceClassName())
.append('.')
.append(record.getSourceMethodName())
.append('/')
.append(record.getLevel().getName())
.append("] ")
.append(message)
.append('\n');
Throwable thrown = record.getThrown();
if (thrown == null) {
return builder.toString();
} else {
StringWriter writer = new StringWriter(builder.length() + 2048);
writer.getBuffer().append(builder);
try (PrintWriter printWriter = new PrintWriter(writer)) {
thrown.printStackTrace(printWriter);
}
return writer.toString();
}
}
private static final class DefaultFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return record.getMessage();
}
}
}

View File

@@ -24,9 +24,8 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.jar.JarOutputStream;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* @author Glavo
@@ -73,7 +72,7 @@ public final class Pack200Utils {
unpack = lookup.findVirtual(unpackerClass, "unpack", MethodType.methodType(void.class, InputStream.class, JarOutputStream.class));
unpackFile = lookup.findVirtual(unpackerClass, "unpack", MethodType.methodType(void.class, File.class, JarOutputStream.class));
} catch (Throwable e) {
LOG.log(Level.WARNING, "Failed to find pack200 methods", e);
LOG.warning("Failed to find pack200 methods", e);
}
if (newUnpacker != null) {

View File

@@ -36,10 +36,9 @@ import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.logging.Level;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* @author huang
@@ -369,7 +368,7 @@ public final class FileUtils {
FileUtils.writeText(infoFile, "[Trash Info]\nPath=" + file.getAbsolutePath() + "\nDeletionDate=" + time + "\n");
FileUtils.forceDelete(file);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to move " + file + " to trash", e);
LOG.warning("Failed to move " + file + " to trash", e);
return false;
}

View File

@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.util.io;
import com.google.gson.JsonParseException;
import fi.iki.elonen.NanoHTTPD;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.function.ExceptionalFunction;
import org.jackhuang.hmcl.util.gson.JsonUtils;
@@ -27,11 +26,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class HttpServer extends NanoHTTPD {
private int traceId = 0;
@@ -54,7 +53,7 @@ public class HttpServer extends NanoHTTPD {
}
protected static Response ok(Object response) {
Logging.LOG.info(String.format("Response %s", JsonUtils.GSON.toJson(response)));
LOG.info(String.format("Response %s", JsonUtils.GSON.toJson(response)));
return newFixedLengthResponse(Response.Status.OK, "text/json", JsonUtils.GSON.toJson(response));
}
@@ -77,7 +76,7 @@ public class HttpServer extends NanoHTTPD {
@Override
public Response serve(IHTTPSession session) {
int currentId = traceId++;
Logging.LOG.info(String.format("[%d] %s --> %s", currentId, session.getMethod().name(),
LOG.info(String.format("[%d] %s --> %s", currentId, session.getMethod().name(),
session.getUri() + Optional.ofNullable(session.getQueryParameterString()).map(s -> "?" + s).orElse("")));
Response response = null;
@@ -92,7 +91,7 @@ public class HttpServer extends NanoHTTPD {
}
if (response == null) response = notFound();
Logging.LOG.info(String.format("[%d] %s <--", currentId, response.getStatus()));
LOG.info(String.format("[%d] %s <--", currentId, response.getStatus()));
return response;
}
@@ -131,7 +130,7 @@ public class HttpServer extends NanoHTTPD {
} catch (JsonParseException e) {
return badRequest();
} catch (Exception e) {
Logging.LOG.log(Level.SEVERE, "Error handling " + request.getSession().getUri(), e);
LOG.error("Error handling " + request.getSession().getUri(), e);
return internalError();
}
}

View File

@@ -0,0 +1,29 @@
package org.jackhuang.hmcl.util.logging;
/**
* @author Glavo
*/
final class CallerFinder {
static String getCaller() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
int i = 0;
while (i++ < stackTrace.length) {
if (stackTrace[i].getClassName().equals(Logger.CLASS_NAME))
break;
}
while (i++ < stackTrace.length) {
StackTraceElement element = stackTrace[i];
String cname = element.getClassName();
if (!cname.equals(Logger.CLASS_NAME) && !cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
return cname + '.' + element.getMethodName();
}
}
return null;
}
private CallerFinder() {
}
}

View File

@@ -0,0 +1,8 @@
package org.jackhuang.hmcl.util.logging;
/**
* @author Glavo
*/
public enum Level {
ERROR, WARNING, INFO, DEBUG, TRACE
}

View File

@@ -0,0 +1,44 @@
package org.jackhuang.hmcl.util.logging;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.CountDownLatch;
/**
* @author Glavo
*/
abstract class LogEvent {
static final class DoLog extends LogEvent {
final long time;
final String caller;
final Level level;
final String message;
final Throwable exception;
DoLog(long time, String caller, Level level, String message, Throwable exception) {
this.time = time;
this.caller = caller;
this.level = level;
this.message = message;
this.exception = exception;
}
}
static final class ExportLog extends LogEvent {
final CountDownLatch latch = new CountDownLatch(1);
final OutputStream output;
IOException exception;
ExportLog(OutputStream output) {
this.output = output;
}
void await() throws InterruptedException {
latch.await();
}
}
static final class Shutdown extends LogEvent {
}
}

View File

@@ -0,0 +1,349 @@
package org.jackhuang.hmcl.util.logging;
import org.jackhuang.hmcl.util.Pair;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.XZOutputStream;
import java.io.*;
import java.nio.file.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
/**
* @author Glavo
*/
public final class Logger {
public static final Logger LOG = new Logger();
private static volatile String[] accessTokens = new String[0];
public static synchronized void registerAccessToken(String token) {
final String[] oldAccessTokens = accessTokens;
final String[] newAccessTokens = Arrays.copyOf(oldAccessTokens, oldAccessTokens.length + 1);
newAccessTokens[oldAccessTokens.length] = token;
accessTokens = newAccessTokens;
}
public static String filterForbiddenToken(String message) {
for (String token : accessTokens)
message = message.replace(token, "<access token>");
return message;
}
static final String CLASS_NAME = Logger.class.getName();
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss").withZone(ZoneId.systemDefault());
private final BlockingQueue<LogEvent> queue = new LinkedBlockingQueue<>();
private final StringBuilder builder = new StringBuilder(512);
private Path logFile;
private ByteArrayOutputStream rawLogs;
private PrintWriter logWriter;
private Thread loggerThread;
private boolean shutdown = false;
private int logRetention = 0;
public void setLogRetention(int logRetention) {
this.logRetention = Math.max(0, logRetention);
}
private String format(LogEvent.DoLog event) {
StringBuilder builder = this.builder;
builder.setLength(0);
builder.append('[');
TIME_FORMATTER.formatTo(Instant.ofEpochMilli(event.time), builder);
builder.append("] [")
.append(event.caller)
.append('/')
.append(event.level)
.append("] ")
.append(filterForbiddenToken(event.message));
return builder.toString();
}
private void handle(LogEvent event) {
if (event instanceof LogEvent.DoLog) {
String log = format((LogEvent.DoLog) event);
Throwable exception = ((LogEvent.DoLog) event).exception;
System.out.println(log);
if (exception != null)
exception.printStackTrace(System.out);
logWriter.println(log);
if (exception != null)
exception.printStackTrace(logWriter);
} else if (event instanceof LogEvent.ExportLog) {
LogEvent.ExportLog exportEvent = (LogEvent.ExportLog) event;
logWriter.flush();
try {
if (logFile != null) {
Files.copy(logFile, exportEvent.output);
} else {
rawLogs.writeTo(exportEvent.output);
}
} catch (IOException e) {
exportEvent.exception = e;
} finally {
exportEvent.latch.countDown();
}
} else if (event instanceof LogEvent.Shutdown) {
shutdown = true;
} else {
throw new AssertionError("Unknown event: " + event);
}
}
private void onShutdown() {
try {
loggerThread.join();
} catch (InterruptedException ignored) {
}
String caller = CLASS_NAME + ".onShutdown";
if (logRetention > 0 && logFile != null) {
List<Pair<Path, int[]>> list = new ArrayList<>();
Pattern fileNamePattern = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})T(?<hour>\\d{2})-(?<minute>\\d{2})-(?<second>\\d{2})(\\.(?<n>\\d+))?\\.log(\\.(gz|xz))?");
Path dir = logFile.getParent();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path path : stream) {
Matcher matcher = fileNamePattern.matcher(path.getFileName().toString());
if (matcher.matches() && Files.isRegularFile(path)) {
int year = Integer.parseInt(matcher.group("year"));
int month = Integer.parseInt(matcher.group("month"));
int day = Integer.parseInt(matcher.group("day"));
int hour = Integer.parseInt(matcher.group("hour"));
int minute = Integer.parseInt(matcher.group("minute"));
int second = Integer.parseInt(matcher.group("second"));
int n = Optional.ofNullable(matcher.group("n")).map(Integer::parseInt).orElse(0);
list.add(Pair.pair(path, new int[]{year, month, day, hour, minute, second, n}));
}
}
} catch (IOException e) {
log(Level.WARNING, caller, "Failed to list log files in " + dir, e);
}
if (list.size() <= logRetention) {
return;
}
list.sort((a, b) -> {
int[] v1 = a.getValue();
int[] v2 = b.getValue();
assert v1.length == v2.length;
for (int i = 0; i < v1.length; i++) {
int c = Integer.compare(v1[i], v2[i]);
if (c != 0)
return c;
}
return 0;
});
for (int i = 0, end = list.size() - logRetention; i < end; i++) {
Path file = list.get(i).getKey();
try {
if (!Files.isSameFile(file, logFile)) {
log(Level.INFO, caller, "Delete old log file " + file, null);
Files.delete(file);
}
} catch (IOException e) {
log(Level.WARNING, caller, "Failed to delete log file " + file, e);
}
}
}
ArrayList<LogEvent> logs = new ArrayList<>();
queue.drainTo(logs);
for (LogEvent log : logs) {
handle(log);
}
if (logFile == null) {
return;
}
boolean failed = false;
Path xzFile = logFile.resolveSibling(logFile.getFileName() + ".xz");
try (XZOutputStream output = new XZOutputStream(Files.newOutputStream(xzFile), new LZMA2Options())) {
logWriter.flush();
Files.copy(logFile, output);
} catch (IOException e) {
failed = true;
handle(new LogEvent.DoLog(System.currentTimeMillis(), caller, Level.WARNING, "Failed to dump log file to xz format", e));
} finally {
logWriter.close();
}
if (!failed)
try {
Files.delete(logFile);
} catch (IOException e) {
System.err.println("An exception occurred while deleting raw log file");
e.printStackTrace(System.err);
}
}
public void start(Path logFolder) {
if (logFolder != null) {
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss"));
try {
for (int n = 0; ; n++) {
Path file = logFolder.resolve(time + (n == 0 ? "" : "." + n) + ".log").toAbsolutePath().normalize();
try {
logWriter = new PrintWriter(Files.newBufferedWriter(file, UTF_8, CREATE_NEW));
logFile = file;
break;
} catch (FileAlreadyExistsException ignored) {
}
}
} catch (IOException e) {
log(Level.WARNING, CLASS_NAME + ".start", "Failed to create log file", e);
}
}
if (logWriter == null) {
rawLogs = new ByteArrayOutputStream(256 * 1024);
logWriter = new PrintWriter(new OutputStreamWriter(rawLogs, UTF_8));
}
loggerThread = new Thread(() -> {
ArrayList<LogEvent> logs = new ArrayList<>();
try {
while (!shutdown) {
if (queue.drainTo(logs) > 0) {
for (LogEvent log : logs) {
handle(log);
}
logs.clear();
} else {
logWriter.flush();
handle(queue.take());
}
}
while (queue.drainTo(logs) > 0) {
for (LogEvent log : logs) {
handle(log);
}
logs.clear();
}
} catch (InterruptedException e) {
throw new AssertionError("This thread cannot be interrupted", e);
}
});
loggerThread.setName("HMCL Logger Thread");
loggerThread.start();
Thread cleanerThread = new Thread(this::onShutdown);
cleanerThread.setName("HMCL Logger Shutdown Hook");
Runtime.getRuntime().addShutdownHook(cleanerThread);
}
public void shutdown() {
queue.add(new LogEvent.Shutdown());
}
public Path getLogFile() {
return logFile;
}
public void exportLogs(OutputStream output) throws IOException {
Objects.requireNonNull(output);
LogEvent.ExportLog event = new LogEvent.ExportLog(output);
try {
queue.put(event);
event.await();
} catch (InterruptedException e) {
throw new AssertionError("This thread cannot be interrupted", e);
}
if (event.exception != null) {
throw event.exception;
}
}
public String getLogs() {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
exportLogs(output);
return output.toString("UTF-8");
} catch (IOException e) {
log(Level.WARNING, CLASS_NAME + ".getLogs", "Failed to export logs", e);
return "";
}
}
private void log(Level level, String caller, String msg, Throwable exception) {
queue.add(new LogEvent.DoLog(System.currentTimeMillis(), caller, level, msg, exception));
}
public void log(Level level, String msg) {
log(level, CallerFinder.getCaller(), msg, null);
}
public void log(Level level, String msg, Throwable exception) {
log(level, CallerFinder.getCaller(), msg, exception);
}
public void error(String msg) {
log(Level.ERROR, CallerFinder.getCaller(), msg, null);
}
public void error(String msg, Throwable exception) {
log(Level.ERROR, CallerFinder.getCaller(), msg, exception);
}
public void warning(String msg) {
log(Level.WARNING, CallerFinder.getCaller(), msg, null);
}
public void warning(String msg, Throwable exception) {
log(Level.WARNING, CallerFinder.getCaller(), msg, exception);
}
public void info(String msg) {
log(Level.INFO, CallerFinder.getCaller(), msg, null);
}
public void info(String msg, Throwable exception) {
log(Level.INFO, CallerFinder.getCaller(), msg, exception);
}
public void debug(String msg) {
log(Level.DEBUG, CallerFinder.getCaller(), msg, null);
}
public void debug(String msg, Throwable exception) {
log(Level.DEBUG, CallerFinder.getCaller(), msg, exception);
}
public void trace(String msg) {
log(Level.TRACE, CallerFinder.getCaller(), msg, null);
}
public void trace(String msg, Throwable exception) {
log(Level.TRACE, CallerFinder.getCaller(), msg, exception);
}
}

View File

@@ -26,7 +26,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class CommandBuilder {
private static final Pattern UNSTABLE_OPTION_PATTERN = Pattern.compile("-XX:(?<key>[a-zA-Z0-9]+)=(?<value>.*)");

View File

@@ -30,13 +30,12 @@ import java.io.InputStreamReader;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Represents a Java installation.
@@ -222,7 +221,7 @@ public final class JavaVersion {
try {
currentExecutable = currentExecutable.toRealPath();
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to resolve current Java path: " + currentExecutable, e);
LOG.warning("Failed to resolve current Java path: " + currentExecutable, e);
}
CURRENT_JAVA = new JavaVersion(
currentExecutable,
@@ -250,7 +249,7 @@ public final class JavaVersion {
try (Stream<Path> stream = searchPotentialJavaExecutables()) {
javaVersions = lookupJavas(stream);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to search Java homes", e);
LOG.warning("Failed to search Java homes", e);
javaVersions = new ArrayList<>();
}
@@ -262,7 +261,7 @@ public final class JavaVersion {
JAVAS = Collections.newSetFromMap(new ConcurrentHashMap<>());
JAVAS.addAll(javaVersions);
LOG.log(Level.FINE, "Finished Java installation lookup, found " + JAVAS.size());
LOG.trace("Finished Java installation lookup, found " + JAVAS.size());
LATCH.countDown();
}
@@ -274,7 +273,7 @@ public final class JavaVersion {
try {
return Stream.of(executable.toRealPath());
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to lookup Java executable at " + executable, e);
LOG.warning("Failed to lookup Java executable at " + executable, e);
return Stream.empty();
}
})
@@ -284,13 +283,13 @@ public final class JavaVersion {
return Stream.of(CURRENT_JAVA);
}
try {
LOG.log(Level.FINER, "Looking for Java:" + executable);
LOG.trace("Looking for Java:" + executable);
Future<JavaVersion> future = Schedulers.io().submit(() -> fromExecutable(executable));
JavaVersion javaVersion = future.get(5, TimeUnit.SECONDS);
LOG.log(Level.FINE, "Found Java (" + javaVersion.getVersion() + ") " + javaVersion.getBinary().toString());
LOG.trace("Found Java (" + javaVersion.getVersion() + ") " + javaVersion.getBinary().toString());
return Stream.of(javaVersion);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
LOG.log(Level.WARNING, "Failed to determine Java at " + executable, e);
LOG.warning("Failed to determine Java at " + executable, e);
return Stream.empty();
}
})
@@ -393,7 +392,7 @@ public final class JavaVersion {
try {
homes.add(Paths.get(home));
} catch (InvalidPathException e) {
LOG.log(Level.WARNING, "Invalid Java path in system registry: " + home);
LOG.warning("Invalid Java path in system registry: " + home);
}
}
}
@@ -439,15 +438,4 @@ public final class JavaVersion {
}
return null;
}
// ====
public static void main(String[] args) {
try {
LOG.setLevel(Level.ALL);
initialize();
LOG.info(JAVAS.toString());
} catch (Throwable e) {
LOG.log(Level.WARNING, "Oops:", e);
}
}
}

View File

@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class SystemUtils {
private SystemUtils() {}