Skip to content

Commit

Permalink
Merge pull request #94 from hkupty/cleanups-and-updates
Browse files Browse the repository at this point in the history
JDK21: Further cleanups and improvements
  • Loading branch information
hkupty authored Mar 20, 2024
2 parents 73a12a6 + 093b7b6 commit cd53f1d
Show file tree
Hide file tree
Showing 34 changed files with 201 additions and 230 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,26 @@ the PATCH component is omitted when its value is `0`.

## Unreleased

### `penna-api`

#### Changed

- Replace configuration interfaces([#89](https://github.com/hkupty/penna/pull/89))

### `penna-core`

#### Changed

- Replace internal MDC storage implementation([#83](https://github.com/hkupty/penna/pull/83))
- Remove ad-hoc configuration mechanism([#89](https://github.com/hkupty/penna/pull/89))
- Remove sink proxy([#94](https://github.com/hkupty/penna/pull/94))
- Minor cleanups and adjusts for JDK21 ([#94](https://github.com/hkupty/penna/pull/94))

### `penna-yaml-config`

#### Changed

- Restructure configuration; implement new interface([#89](https://github.com/hkupty/penna/pull/89))

## 0.7.2

Expand Down
75 changes: 22 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ In order to use it, add it to the [build manager of your preference](https://mvn

```groovy
// gradle
runtimeOnly 'com.hkupty.penna:penna-core:0.7.0'
runtimeOnly 'com.hkupty.penna:penna-core:0.8.0'
// Penna doesn't have any strict dependencies aside from slf4j.
implementation 'org.slf4j:slf4j-api:2.0.9'
implementation 'org.slf4j:slf4j-api:2.0.12'
```

:warning: Note that Penna is built targeting JVM 17+.
:warning: Note that Penna is built targeting JVM 21+.

By default, you will get log level `INFO` enabled as well as the following fields:
- `timestamp`
Expand All @@ -58,68 +58,37 @@ By default, you will get log level `INFO` enabled as well as the following field
- `data` (slf4j's 2.0 `.addKeyValue()`)
- `throwable`

Penna has support for logging also a `Counter` to each message, individually marking each message with a monotonically increasing
`long` counting from process startup, but that is disabled by default.

If you want to configure it, Penna provides a separate convenience library for configuring your log levels in yaml files:
```yaml
# resources/penna.yaml

# This is for configuring the root level
penna:
# We don't need to set level because by default it is set to INFO
fields:
# Not that it matter for json, but the key-value pairs below will be rendered in this order.
# So, for human readability in the console, one can tweak the position of the fields:
- level
- logger
- thread
- data
- mdc
- markers
- message
- throwable
loggers:
# This map will match the logger with the same literal name and all its children loggers, so
# com.mycompany.myapp as well as com.mycompany.myapp.controllers.MyGreatController and so on..
com.mycompany.myapp:
level: debug
# There's no need to set fields here since it will inherit from the root logger
com.vendor.noisylib:
level: warn
fields:
# USE WITH CAUTION! You can opt to remove/add fields to the message in different loggers
# In this example, we're removing `thread`, `data`, `mdc` and `markers` and adding the `counter` field.
# This means the log messages from `com.vendor.noisylib` will be rendered differently.
- level
- logger
- message
- throwable
---
# Since version 0.8, penna-yaml-config supports setting up a file watcher
# so any updates to this file will be reflected immediately
watch: true
loggers:
# All the loggers under `com.yourapp` will be configured to debug level.
com.yourapp: { level: debug }
org.noisylibrary: { level: warn }
```
If you want to use [penna-yaml-config](penna-yaml-config/README.md), you have to add it as a dependency:
```groovy
runtimeOnly 'com.hkupty.penna:penna-yaml-config:0.7.0'
runtimeOnly 'com.hkupty.penna:penna-yaml-config:0.8.0'

// We have to add a yaml parser to the classpath for `penna-yaml-config` to work properly.
// Currently we only support `jackson-dataformat-yaml`, but we plan on adding support for other libraries.
runtimeOnly 'com.fasterxml.jackson.core:jackson-core:2.14.2'
runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
runtimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2'
```
// penna-yaml-config is a thin layer and uses a yaml parsing libray under the hood.
// You can chose among jackson, snakeyaml (yaml 1.1) or snakeyaml engine (yaml 1.2)

## Test logs
// Jackson
runtimeOnly 'com.fasterxml.jackson.core:jackson-core:2.17.0'
runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:2.17.0'
runtimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.0'

Starting from Penna 0.7, Penna offers a `penna-dev` module which reformats the log to standard formatted strings instead of json.
By adding `penna-dev` to your test runtime it will automatically bind the new logger on top of `penna-core`

```groovy
// penna-core is still needed as a runtime dependency
runtimeOnly 'com.hkupty.penna:penna-core:0.7.0'
// Snakeyaml
runtimeOnly 'org.yaml:snakeyaml:2.2'

// penna-dev should only be added to the test runtime
testRuntimeOnly 'com.hkupty.penna:penna-dev:0.7.0'
// Snakeyaml engine
runtimeOnly 'org.snakeyaml:snakeyaml-engine:2.7'
```

## Principles
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=0.7.2
version=0.8.0-rc1
3 changes: 1 addition & 2 deletions penna-api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import penna.api.configv2.Provider;
import penna.api.config.Provider;

/**
* Penna API is a thin set of classes and records that are common-ground between the {@code penna.core} project
Expand All @@ -13,5 +13,4 @@

exports penna.api.models;
exports penna.api.config;
exports penna.api.configv2;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package penna.api.configv2;

import penna.api.config.Config;
package penna.api.config;

/**
* Class exists to contextually bind a configuration object to a logger by its name.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package penna.api.configv2;

import penna.api.config.Config;
package penna.api.config;

import java.util.Objects;
import java.util.ServiceLoader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package penna.api.configv2;
package penna.api.config;

/**
* This interface allows for additional configuration providers to interact with the logger setup.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package penna.api.configv2;

import penna.api.config.Config;
package penna.api.config;

/**
* A Config Storage defines a class that stores the configurations for all logs in the hierarchy.
Expand Down
9 changes: 0 additions & 9 deletions penna-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import penna.core.slf4j.PennaServiceProvider;

module penna.core {
uses penna.core.sink.NonStandardSink;
// Depends explicitly on the SLF4J api
requires org.slf4j;
requires transitive penna.api;

// Exposes a service provider for SLF4j
provides org.slf4j.spi.SLF4JServiceProvider with PennaServiceProvider;


// Penna subprojects also have access to minilog
// when/if breaking apart from slf4j, expose the full logger
exports penna.core.minilog to penna.config.yaml;
exports penna.core.sink to penna.dev;
exports penna.core.slf4j to penna.dev;
exports penna.core.models to penna.dev;
}
2 changes: 1 addition & 1 deletion penna-core/src/main/java/penna/core/internals/Clock.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private Clock() {}
* increment the clock every X nanoseconds as defined by {@link Clock#REFRESH_RATE} and after every
* Y iterations, as defined by {@link Clock#PRECISION}, we sync back with the system clock.
*/
private static final Thread clockThread = ThreadCreator.newThread("penna-clock-ticker", () -> {
private static final Thread clockThread = Thread.ofVirtual().name("penna-clock-ticker").start(() -> {
while(!Thread.currentThread().isInterrupted()) {
var ts = timestamp.incrementAndGet();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public final class DirectJson implements Closeable {
private static final int INITIAL_BUFFER_SIZE = 2 * 1024;
private int highWatermark = (int) Math.ceil(INITIAL_BUFFER_SIZE * 0.8);
private static final byte[] LINE_BREAK = System.getProperty("line.separator").getBytes(StandardCharsets.UTF_8);
private static final byte[] LINE_BREAK = System.lineSeparator().getBytes(StandardCharsets.UTF_8);
private static final byte QUOTE = '"';
private static final byte ENTRY_SEP = ':';
private static final byte KV_SEP = ',';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package penna.core.internals;

import org.jetbrains.annotations.VisibleForTesting;
import penna.core.logger.LogUnitContext;
import penna.core.models.PennaLogEvent;
import penna.core.sink.SinkManager;
import penna.core.sink.CoreSink;
import penna.core.sink.Sink;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;

/**
* This Object Pool ensures each thread will have access to a single pooled {@link LogUnitContext},
Expand All @@ -26,7 +29,7 @@ public final class LogUnitContextPool {
private final LogUnitContext[] objectGroup;

private LogUnitContext leafObject(int index) {
return new LogUnitContext(this, index, SinkManager.Instance.get(), new PennaLogEvent());
return new LogUnitContext(this, index, CoreSink.getSink(), new PennaLogEvent());
}

public LogUnitContextPool() {
Expand All @@ -39,6 +42,13 @@ public LogUnitContextPool() {
}
}

@VisibleForTesting
void refillThePool(Supplier<Sink> sinkSupplier) {
for (int i = 0; i < objectGroup.length; i++) {
objectGroup[i] = new LogUnitContext(this, i, sinkSupplier.get(), objectGroup[i].logEvent());
}
}

public void release(int index) {
locks[index].unlock();
}
Expand Down
24 changes: 0 additions & 24 deletions penna-core/src/main/java/penna/core/internals/ThreadCreator.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package penna.core.internals.store;

import java.io.Serial;
import java.util.Map;
import java.util.TreeMap;

Expand All @@ -13,6 +14,9 @@
*/
public final class StringTreeMap extends TreeMap<String, String> implements StringMap {

@Serial
private static final long serialVersionUID = 23827L;

public StringTreeMap() {
super();
}
Expand Down
18 changes: 8 additions & 10 deletions penna-core/src/main/java/penna/core/logger/LoggerStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ public static Node create(String component, Config config) {
public final Lock lock = new ReentrantLock();


void setConfigAndUpdateRecursively(Config baseConfig) {
void setConfigAndUpdateRecursively(@NotNull Config baseConfig) {
lock.lock();
try {
configRef = baseConfig;

if (loggerRef != null && baseConfig != null) {
if (loggerRef != null) {
loggerRef.updateConfig(baseConfig);
}
} finally {
Expand All @@ -74,14 +74,18 @@ void setConfigAndUpdateRecursively(Config baseConfig) {
if (children[1] != null) {children[1].updateRecursively(baseConfig);}
}

void updateRecursively(Config baseConfig) {
void updateRecursively(@NotNull Config baseConfig) {
lock.lock();
try {
if (configRef != null) {
// TODO: This might be a little problematic. Needs to be investigated further
// A Configuration object might need a stamp so we can differentiate
// a valid replacement (i.e. a newer version is updating old data) from an
// invalid one.
configRef = baseConfig;
}

if (loggerRef != null && baseConfig != null) {
if (loggerRef != null) {
loggerRef.updateConfig(baseConfig);
}
} finally {
Expand Down Expand Up @@ -184,12 +188,6 @@ public Config getConfig(@NotNull String prefix) {
}

public void replaceConfig(@NotNull Config newConfig) {
root.lock.lock();
try {
root.configRef = newConfig;
} finally {
root.lock.unlock();
}
root.updateRecursively(newConfig);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package penna.core.logger.guard;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.event.Level;
import org.slf4j.spi.LoggingEventBuilder;
import org.slf4j.spi.NOPLoggingEventBuilder;
Expand All @@ -20,7 +21,8 @@
public sealed interface LevelGuard permits DebugLevelGuard, ErrorLevelGuard, InfoLevelGuard, NOPGuard, TraceLevelGuard, WarnLevelGuard {

final class Shared {
private static final LogUnitContextPool logUnits = new LogUnitContextPool();
@VisibleForTesting
public static final LogUnitContextPool logUnits = new LogUnitContextPool();
}

final class FromConfig {
Expand Down
Loading

0 comments on commit cd53f1d

Please sign in to comment.