Skip to content

Commit

Permalink
Add more uniqueid options (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
wsargent authored Jan 16, 2023
1 parent 1a99621 commit 22170e9
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 16 deletions.
60 changes: 55 additions & 5 deletions docs/guide/uniqueid.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,64 @@ To extract the unique ID, register a converter:

## ID Generators

Unique IDs come with two different options. Flake ID is the default.

### Random UUID

This implementation uses `RandomBasedGenerator` from [Java UUID Generator](https://github.com/cowtowncoder/java-uuid-generator/). This is faster than using `java.util.UUID.randomUUID`, because it avoids the [synchronization lock](https://braveo.blogspot.com/2013/05/uuidrandomuuid-is-slow.html).
Unique IDs come with several options. Flake ID is the default.

### Flake ID

Flake IDs are decentralized and k-ordered, meaning that they are "roughly time-ordered when sorted lexicographically."

This implementation uses [idem](https://github.com/mguenther/idem) with `Flake128S`.

```xml
<appender name="selector-with-unique-id" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<idGenerator class="com.tersesystems.logback.uniqueid.FlakeIdGenerator"/>
<!-- ... -->
</appender>
```

### Random UUID

Generates a Random UUIDv4 using a ThreadLocalRandom according to <a href="https://github.com/f4b6a3/uuid-creator">https://github.com/f4b6a3/uuid-creator</a>.

```xml
<appender name="selector-with-unique-id" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<idGenerator class="com.tersesystems.logback.uniqueid.RandomUUIDIdGenerator"/>
<!-- ... -->
</appender>
```

## TSID Generator

Generates a TSID according to <a href="https://github.com/f4b6a3/tsid-creator">https://github.com/f4b6a3/tsid-creator</a>.

**Highly recommended to set a *tsidcreator.node* system property in your application to configure the node id.

```xml
<appender name="selector-with-unique-id" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<idGenerator class="com.tersesystems.logback.uniqueid.TsidIdgenerator"/>
<!-- ... -->
</appender>
```

## ULID Generator

Creates a monotonic ULID using a threadlocal random according to <a href="https://github.com/f4b6a3/ulid-creator">https://github.com/f4b6a3/ulid-creator</a>.

```xml
<appender name="selector-with-unique-id" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<idGenerator class="com.tersesystems.logback.uniqueid.UlidIdGenerator"/>
<!-- ... -->
</appender>
```

## KSU ID Generator

Creates a subsecond KSUID according to <a href="https://github.com/f4b6a3/ksuid-creator">https://github.com/f4b6a3/ksuid-creator</a>.

```xml
<appender name="selector-with-unique-id" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<idGenerator class="com.tersesystems.logback.uniqueid.KsuidSubsecondIdGenerator"/>
<!-- ... -->
</appender>
```

14 changes: 13 additions & 1 deletion logback-uniqueid-appender/logback-uniqueid-appender.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@
dependencies {
implementation project(':logback-classic')

implementation group: 'com.fasterxml.uuid', name: 'java-uuid-generator', version: '3.2.0'
// https://github.com/f4b6a3/ulid-creator
implementation 'com.github.f4b6a3:ulid-creator:5.1.0'

// https://github.com/f4b6a3/tsid-creator
implementation 'com.github.f4b6a3:tsid-creator:5.1.0'

// https://github.com/f4b6a3/uuid-creator
implementation 'com.github.f4b6a3:uuid-creator:5.2.0'

// https://github.com/f4b6a3/ksuid-creator
implementation 'com.github.f4b6a3:ksuid-creator:4.1.0'

// https://github.com/mguenther/idem
implementation 'net.mguenther.idem:idem-core:0.1.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@

import net.mguenther.idem.flake.Flake128S;
import net.mguenther.idem.provider.LinearTimeProvider;
import net.mguenther.idem.provider.StaticWorkerIdProvider;
import net.mguenther.idem.provider.MacAddressWorkerIdProvider;

/**
* This class generates a 128 bit flake id with a macaddress workerid according to <a
* href="https://github.com/mguenther/idem">https://github.com/mguenther/idem</a>.
*/
public class FlakeIdGenerator implements IdGenerator {

private static final Flake128S flake64 =
new Flake128S(new LinearTimeProvider(), new StaticWorkerIdProvider("logback"));
new Flake128S(new LinearTimeProvider(), new MacAddressWorkerIdProvider());

@Override
public String generateId() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.tersesystems.logback.uniqueid;

import com.github.f4b6a3.ksuid.*;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/**
* Creates a subsecond KSUID according to <a
* href="https://github.com/f4b6a3/ksuid-creator">https://github.com/f4b6a3/ksuid-creator</a>.
*/
public class KsuidSubsecondIdGenerator implements IdGenerator {

private Random random() {
return ThreadLocalRandom.current();
}

private final KsuidFactory factory = KsuidFactory.newSubsecondInstance(() -> random().nextLong());

@Override
public String generateId() {
return factory.create().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@
*/
package com.tersesystems.logback.uniqueid;

import com.fasterxml.uuid.impl.RandomBasedGenerator;
import com.github.f4b6a3.uuid.factory.rfc4122.RandomBasedFactory;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/**
* Generates a Random UUIDv4 using a ThreadLocalRandom from <a
* href="https://github.com/f4b6a3/uuid-creator">https://github.com/f4b6a3/uuid-creator</a>
*/
public class RandomUUIDIdGenerator implements IdGenerator {
private Random random() {
return ThreadLocalRandom.current();
}

// Using java.util.UUID.fromRandom() has thread contention issues due to synchronized block.
private static final RandomBasedGenerator idgen = new RandomBasedGenerator(null);
private final RandomBasedFactory factory = new RandomBasedFactory(() -> random().nextLong());

@Override
public String generateId() {
return idgen.generate().toString();
return factory.create().toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tersesystems.logback.uniqueid;

import com.github.f4b6a3.tsid.TsidFactory;

/**
* Generates a TSID according to <a
* href="https://github.com/f4b6a3/tsid-creator">https://github.com/f4b6a3/tsid-creator</a>.
*/
public class TsidIdgenerator implements IdGenerator {

// "tsidcreator.node" system property should be set,
// but small hope of that happening, so choose a large node count.
private final TsidFactory factory = TsidFactory.newInstance4096();

@Override
public String generateId() {
return factory.create().toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.tersesystems.logback.uniqueid;

import com.github.f4b6a3.ulid.UlidFactory;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/**
* Creates a monotonic ULID using a threadlocal random according to <a
* href="https://github.com/f4b6a3/ulid-creator">https://github.com/f4b6a3/ulid-creator</a>.
*/
public class UlidIdGenerator implements IdGenerator {

private Random random() {
return ThreadLocalRandom.current();
}

private final UlidFactory factory = UlidFactory.newMonotonicInstance(() -> random().nextLong());

@Override
public String generateId() {
return factory.create().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@
<conversionRule conversionWord="uniqueId" converterClass="com.tersesystems.logback.uniqueid.UniqueIdConverter" />

<appender name="DECORATE_WITH_UNIQUEID" class="com.tersesystems.logback.uniqueid.UniqueIdComponentAppender">
<!-- <idGenerator class="com.tersesystems.logback.uniqueid.TsidIdgenerator"/>-->
<!--<idGenerator class="com.tersesystems.logback.uniqueid.UlidIdGenerator"/>-->
<!--<idGenerator class="com.tersesystems.logback.uniqueid.KsuidSubsecondIdGenerator"/>-->
<idGenerator class="com.tersesystems.logback.uniqueid.RandomUUIDIdGenerator"/>
<appender class="ch.qos.logback.core.read.ListAppender">
<name>LIST</name>
</appender>

<appender class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5relative %-5level %uniqueId %logger{35} - %msg%n</pattern>
</encoder>
</appender>

<appender class="ch.qos.logback.core.read.ListAppender">
<name>LIST</name>
</appender>
</appender>

<root level="TRACE">
Expand Down

0 comments on commit 22170e9

Please sign in to comment.