Add logging abstraction

This commit is contained in:
Johannes Frohnmeyer 2022-05-09 19:09:34 +02:00
parent 9196b77e5c
commit b4cb5c3c73
Signed by: Johannes
GPG Key ID: E76429612C2929F4
12 changed files with 515 additions and 79 deletions

View File

@ -1,31 +1,62 @@
plugins {
id 'java-library'
id 'maven-publish'
}
var cl = Calendar.instance
var day = "${cl.get(cl.YEAR)}.${cl.get(cl.MONTH) + 1}.${cl.get(cl.DATE)}"
var time = "${cl.get(cl.HOUR_OF_DAY)}.${cl.get(cl.MINUTE)}.${cl.get(cl.SECOND)}"
var time = "${cl.get(cl.HOUR_OF_DAY)}-${cl.get(cl.MINUTE)}-${cl.get(cl.SECOND)}"
version = "0.1.0.$day.$time"
allprojects {
apply plugin: 'java-library'
apply plugin: 'maven-publish'
repositories {
mavenCentral()
version = "$day+$time"
repositories {
mavenCentral()
maven {
url 'https://gitlab.com/api/v4/projects/35030495/packages/maven'
}
}
dependencies {
compileOnly 'org.jetbrains:annotations:23.0.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
test {
useJUnitPlatform()
}
java {
withSourcesJar()
}
publishing {
def ENV = System.getenv()
if (project.hasProperty("maven")) {
repositories.maven {
url = project.getProperty("maven")
name = "dynamic"
credentials(HttpHeaderCredentials) {
name = "Job-Token"
value = ENV.CI_JOB_TOKEN
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
repositories.mavenLocal()
}
}
dependencies {
compileOnly 'org.jetbrains:annotations:23.0.0'
subprojects {
dependencies {
implementation project(':')
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
test {
useJUnitPlatform()
}
java {
withSourcesJar()
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
}
publishing {
@ -37,21 +68,4 @@ publishing {
from components.java
}
}
def ENV = System.getenv()
if (project.hasProperty("maven")) {
repositories.maven {
url = project.getProperty("maven")
name = "dynamic"
credentials(HttpHeaderCredentials) {
name = "Job-Token"
value = ENV.CI_JOB_TOKEN
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
repositories.mavenLocal()
}

View File

@ -1,25 +1,9 @@
plugins {
id 'java-library'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
version = rootProject.version
repositories {
mavenCentral()
maven {
url 'https://gitlab.com/api/v4/projects/35030495/packages/maven'
}
}
dependencies {
shadow implementation('io.gitlab.jfronny:gson:+')
implementation project(':')
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
shadowJar {
@ -27,14 +11,6 @@ shadowJar {
archiveClassifier = ''
}
test {
useJUnitPlatform()
}
java {
withSourcesJar()
}
publishing {
publications {
mavenJava(MavenPublication) {
@ -52,21 +28,4 @@ publishing {
}
}
}
def ENV = System.getenv()
if (project.hasProperty("maven")) {
repositories.maven {
url = project.getProperty("maven")
name = "dynamic"
credentials(HttpHeaderCredentials) {
name = "Job-Token"
value = ENV.CI_JOB_TOKEN
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
repositories.mavenLocal()
}

View File

@ -0,0 +1,14 @@
dependencies {
implementation "org.slf4j:slf4j-api:1.7.36"
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'io.gitlab.jfronny'
artifactId = 'commons-slf4j'
from components.java
}
}
}

View File

@ -0,0 +1,116 @@
package io.gitlab.jfronny.commons.log;
import org.slf4j.LoggerFactory;
public class SLF4JLogger implements Logger {
private final org.slf4j.Logger logger;
public SLF4JLogger(String name) {
this.logger = LoggerFactory.getLogger(name);
}
@Override
public String getName() {
return logger.getName();
}
@Override
public void trace(String msg) {
logger.trace(msg);
}
@Override
public void trace(String format, Object arg) {
logger.trace(format, arg);
}
@Override
public void trace(String format, Object... args) {
logger.trace(format, args);
}
@Override
public void trace(String msg, Throwable t) {
logger.trace(msg, t);
}
@Override
public void debug(String msg) {
logger.debug(msg);
}
@Override
public void debug(String format, Object arg) {
logger.debug(format, arg);
}
@Override
public void debug(String format, Object... args) {
logger.debug(format, args);
}
@Override
public void debug(String msg, Throwable t) {
logger.debug(msg, t);
}
@Override
public void info(String msg) {
logger.info(msg);
}
@Override
public void info(String format, Object arg) {
logger.info(format, arg);
}
@Override
public void info(String format, Object... args) {
logger.info(format, args);
}
@Override
public void info(String msg, Throwable t) {
logger.info(msg, t);
}
@Override
public void warn(String msg) {
logger.warn(msg);
}
@Override
public void warn(String format, Object arg) {
logger.warn(format, arg);
}
@Override
public void warn(String format, Object... args) {
logger.warn(format, args);
}
@Override
public void warn(String msg, Throwable t) {
logger.warn(msg, t);
}
@Override
public void error(String msg) {
logger.error(msg);
}
@Override
public void error(String format, Object arg) {
logger.error(format, arg);
}
@Override
public void error(String format, Object... args) {
logger.error(format, args);
}
@Override
public void error(String msg, Throwable t) {
logger.error(msg, t);
}
}

View File

@ -0,0 +1,20 @@
package io.gitlab.jfronny.commons.test;
import io.gitlab.jfronny.commons.log.Logger;
import io.gitlab.jfronny.commons.log.SLF4JLogger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SLFLoggerTest {
@BeforeEach
void prepare() {
Logger.resetFactory();
}
@Test
void testFactory() {
assertEquals(SLF4JLogger.class, Logger.forName("Joe").getClass());
}
}

View File

@ -1,3 +1,5 @@
rootProject.name = 'Commons'
include 'commons-gson'
include 'commons-slf4j'

View File

@ -0,0 +1,116 @@
package io.gitlab.jfronny.commons.log;
import java.util.logging.Level;
public class JavaUtilLogger implements Logger {
private final java.util.logging.Logger logger;
public JavaUtilLogger(String name) {
this.logger = java.util.logging.Logger.getLogger(name);
}
@Override
public String getName() {
return logger.getName();
}
@Override
public void trace(String msg) {
logger.log(Level.FINER, msg);
}
@Override
public void trace(String format, Object arg) {
logger.log(Level.FINER, format, arg);
}
@Override
public void trace(String format, Object... args) {
logger.log(Level.FINER, format, args);
}
@Override
public void trace(String msg, Throwable t) {
logger.log(Level.FINER, msg, t);
}
@Override
public void debug(String msg) {
logger.log(Level.FINE, msg);
}
@Override
public void debug(String format, Object arg) {
logger.log(Level.FINE, format, arg);
}
@Override
public void debug(String format, Object... args) {
logger.log(Level.FINE, format, args);
}
@Override
public void debug(String msg, Throwable t) {
logger.log(Level.FINE, msg, t);
}
@Override
public void info(String msg) {
logger.log(Level.INFO, msg);
}
@Override
public void info(String format, Object arg) {
logger.log(Level.INFO, format, arg);
}
@Override
public void info(String format, Object... args) {
logger.log(Level.INFO, format, args);
}
@Override
public void info(String msg, Throwable t) {
logger.log(Level.INFO, msg, t);
}
@Override
public void warn(String msg) {
logger.log(Level.WARNING, msg);
}
@Override
public void warn(String format, Object arg) {
logger.log(Level.WARNING, format, arg);
}
@Override
public void warn(String format, Object... args) {
logger.log(Level.WARNING, format, args);
}
@Override
public void warn(String msg, Throwable t) {
logger.log(Level.WARNING, msg, t);
}
@Override
public void error(String msg) {
logger.log(Level.SEVERE, msg);
}
@Override
public void error(String format, Object arg) {
logger.log(Level.SEVERE, format, arg);
}
@Override
public void error(String format, Object... args) {
logger.log(Level.SEVERE, format, args);
}
@Override
public void error(String msg, Throwable t) {
logger.log(Level.SEVERE, msg, t);
}
}

View File

@ -0,0 +1,103 @@
package io.gitlab.jfronny.commons.log;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
public interface Logger {
static Logger forName(@NotNull String name) {
return LoggerHolder.LOGGER_BUILDER.apply(name);
}
static void registerFactory(@NotNull Function<String, Logger> factory) {
LoggerHolder.LOGGER_BUILDER = Objects.requireNonNull(factory);
}
static void resetFactory() {
LoggerHolder.LOGGER_BUILDER = LoggerHolder.DEFAULT_LOGGER_BUILDER;
}
@Nullable String getName();
default void trace(String msg) {
debug(msg);
}
default void trace(String format, Object arg) {
trace(format(format, arg));
}
default void trace(String format, Object... args) {
trace(format(format, args));
}
default void trace(String msg, Throwable t) {
trace(format(msg, t));
}
default void debug(String msg) {
info(msg);
}
default void debug(String format, Object arg) {
debug(format(format, arg));
}
default void debug(String format, Object... args) {
debug(format(format, args));
}
default void debug(String msg, Throwable t) {
debug(format(msg, t));
}
void info(String msg);
default void info(String format, Object arg) {
info(format(format, arg));
}
default void info(String format, Object... args) {
info(format(format, args));
}
default void info(String msg, Throwable t) {
info(format(msg, t));
}
default void warn(String msg) {
info(msg);
}
default void warn(String format, Object arg) {
warn(format(format, arg));
}
default void warn(String format, Object... args) {
warn(format(format, args));
}
default void warn(String msg, Throwable t) {
warn(format(msg, t));
}
default void error(String msg) {
warn(msg);
}
default void error(String format, Object arg) {
error(format(format, arg));
}
default void error(String format, Object... args) {
error(format(format, args));
}
default void error(String msg, Throwable t) {
error(format(msg, t));
}
default String format(String format, Object arg) {
return format.replaceFirst("\\{}", Objects.toString(arg));
}
default String format(String format, Object... args) {
if (args == null || format == null) return format;
for (Object arg : args) {
format = format.replaceFirst("\\{}", Objects.toString(arg));
}
return format;
}
default String format(String msg, Throwable t) {
if (t == null) return msg;
return msg + System.lineSeparator() + t;
}
}

View File

@ -0,0 +1,27 @@
package io.gitlab.jfronny.commons.log;
import io.gitlab.jfronny.commons.throwable.Coerce;
import io.gitlab.jfronny.commons.throwable.ThrowingFunction;
import org.jetbrains.annotations.ApiStatus;
import java.lang.reflect.Constructor;
import java.util.function.Function;
@ApiStatus.Internal
class LoggerHolder {
public static Function<String, Logger> LOGGER_BUILDER;
public static final Function<String, Logger> DEFAULT_LOGGER_BUILDER;
static {
try {
Constructor<Logger> constructor = (Constructor<Logger>) Class.forName("io.gitlab.jfronny.commons.log.SLF4JLogger")
.getConstructor(String.class);
LOGGER_BUILDER = Coerce.function((ThrowingFunction<String, Logger, Exception>) constructor::newInstance).orThrow();
} catch (ClassNotFoundException | NoSuchMethodException e) {
// SLF4J logger is unavailable, use java.util.logging
LOGGER_BUILDER = JavaUtilLogger::new;
}
DEFAULT_LOGGER_BUILDER = LOGGER_BUILDER;
}
}

View File

@ -0,0 +1,12 @@
package io.gitlab.jfronny.commons.log;
public class NopLogger implements Logger {
@Override
public String getName() {
return null;
}
@Override
public void info(String msg) {
}
}

View File

@ -0,0 +1,26 @@
package io.gitlab.jfronny.commons.log;
public class StdoutLogger implements Logger {
private final String name;
private final String prefix;
public StdoutLogger(String name) {
this.name = name;
this.prefix = "[" + name + "] ";
}
@Override
public String getName() {
return name;
}
@Override
public void info(String msg) {
System.out.println(prefix + msg);
}
@Override
public void warn(String msg) {
System.err.println(prefix + msg);
}
}

View File

@ -0,0 +1,27 @@
package io.gitlab.jfronny.commons.test;
import io.gitlab.jfronny.commons.log.JavaUtilLogger;
import io.gitlab.jfronny.commons.log.Logger;
import io.gitlab.jfronny.commons.log.NopLogger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class LoggerTest {
@BeforeEach
void prepare() {
Logger.resetFactory();
}
@Test
void testFactory() {
assertEquals(JavaUtilLogger.class, Logger.forName("Joe").getClass());
}
@Test
void testRegisterFactory() {
Logger.registerFactory(s -> new NopLogger());
assertEquals(NopLogger.class, Logger.forName("Joe").getClass());
}
}