refactor: change to MIT license and reformat codes
This commit is contained in:
+20
-16
@@ -1,25 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
* Copyright (c) 2024-2025 OnixByte
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.onixbyte.identitygenerator;
|
||||
|
||||
/**
|
||||
* The {@code IdentityGenerator} is a generic interface for generating globally unique identifiers (GUIDs)
|
||||
* of a specific type.
|
||||
* The {@code IdentityGenerator} is a generic interface for generating globally unique identifiers
|
||||
* (GUIDs) of a specific type.
|
||||
* <p>
|
||||
* The type of ID is determined by the class implementing this interface.
|
||||
* </p>
|
||||
@@ -45,9 +50,8 @@ package com.onixbyte.identitygenerator;
|
||||
* }</pre>
|
||||
*
|
||||
* @param <IdType> this represents the type of the Global Unique Identifier
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
* @author zihluwang
|
||||
* @version 3.0.0
|
||||
*/
|
||||
public interface IdentityGenerator<IdType> {
|
||||
|
||||
|
||||
+18
-13
@@ -1,18 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
* Copyright (c) 2024-2025 OnixByte
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.onixbyte.identitygenerator.exceptions;
|
||||
@@ -25,8 +30,8 @@ package com.onixbyte.identitygenerator.exceptions;
|
||||
* provides a description of the exception, while the cause represents the underlying cause of the
|
||||
* exception and provides additional information about the error.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @since 1.0.0
|
||||
* @author zihluwang
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class TimingException extends RuntimeException {
|
||||
|
||||
|
||||
+28
-18
@@ -1,18 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
* Copyright (c) 2024-2025 OnixByte
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.onixbyte.identitygenerator.impl;
|
||||
@@ -24,15 +29,20 @@ import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A {@code SequentialUuidGenerator} is responsible for generating UUIDs following the UUID version 7 specification, which
|
||||
* combines a timestamp with random bytes to create time-ordered unique identifiers.
|
||||
* A {@code SequentialUuidGenerator} is responsible for generating UUIDs following the
|
||||
* UUID version 7 specification, which combines a timestamp with random bytes to create time-ordered
|
||||
* unique identifiers.
|
||||
* <p>
|
||||
* This implementation utilises a cryptographically strong {@link SecureRandom} instance to produce the random
|
||||
* component of the UUID. The first 6 bytes of the UUID encode the current timestamp in milliseconds, ensuring that
|
||||
* generated UUIDs are roughly ordered by creation time.
|
||||
* This implementation utilises a cryptographically strong {@link SecureRandom} instance to produce
|
||||
* the random component of the UUID. The first 6 bytes of the UUID encode the current timestamp in
|
||||
* milliseconds, ensuring that generated UUIDs are roughly ordered by creation time.
|
||||
* <p>
|
||||
* The generated UUID adheres strictly to the layout and variant bits of UUID version 7 as defined in the specification.
|
||||
* </p>
|
||||
* The generated UUID adheres strictly to the layout and variant bits of UUID version 7 as defined
|
||||
* in the specification.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @author siujamo
|
||||
* @version 3.0.0
|
||||
*/
|
||||
public class SequentialUuidGenerator implements IdentityGenerator<UUID> {
|
||||
|
||||
|
||||
+134
-130
@@ -1,18 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
* Copyright (c) 2024-2025 OnixByte
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.onixbyte.identitygenerator.impl;
|
||||
@@ -35,129 +40,17 @@ import java.time.ZoneId;
|
||||
* <li>12 bits for sequence number (per millisecond)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* When initializing a {@link SnowflakeIdentityGenerator}, you must provide the worker ID and data centre
|
||||
* ID, ensuring they are within the valid range defined by the bit size. The generator maintains an
|
||||
* internal sequence number that increments for IDs generated within the same millisecond. If the
|
||||
* system clock moves backward, an exception is thrown to prevent generating IDs with
|
||||
* repeated timestamps.
|
||||
* When initializing a {@link SnowflakeIdentityGenerator}, you must provide the worker ID and data
|
||||
* centre ID, ensuring they are within the valid range defined by the bit size. The generator
|
||||
* maintains an internal sequence number that increments for IDs generated within the
|
||||
* same millisecond. If the system clock moves backward, an exception is thrown to prevent
|
||||
* generating IDs with repeated timestamps.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
* @author zihluwang
|
||||
* @version 3.0.0
|
||||
*/
|
||||
public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long> {
|
||||
|
||||
/**
|
||||
* Constructs a SnowflakeGuidGenerator with the default start epoch and custom worker ID, data
|
||||
* centre ID.
|
||||
*
|
||||
* @param dataCentreId the data centre ID (between 0 and 31)
|
||||
* @param workerId the worker ID (between 0 and 31)
|
||||
*/
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId) {
|
||||
this(dataCentreId, workerId, DEFAULT_CUSTOM_EPOCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SnowflakeGuidGenerator with a custom epoch, worker ID, and data centre ID.
|
||||
*
|
||||
* @param dataCentreId the data centre ID (between 0 and 31)
|
||||
* @param workerId the worker ID (between 0 and 31)
|
||||
* @param startEpoch the custom epoch timestamp (in milliseconds) to start generating IDs from
|
||||
* @throws IllegalArgumentException if the start epoch is greater than the current timestamp,
|
||||
* or if the worker ID or data centre ID is out of range
|
||||
*/
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId, long startEpoch) {
|
||||
if (startEpoch > currentTimestamp()) {
|
||||
throw new IllegalArgumentException("Start Epoch can not be greater than current timestamp!");
|
||||
}
|
||||
|
||||
var maxWorkerId = ~(-1L << workerIdBits);
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("Worker Id can't be greater than %d or less than 0",
|
||||
maxWorkerId));
|
||||
}
|
||||
|
||||
var maxDataCentreId = ~(-1L << dataCentreIdBits);
|
||||
if (dataCentreId > maxDataCentreId || dataCentreId < 0) {
|
||||
throw new IllegalArgumentException(String.format("Data Centre Id can't be greater than %d or less than 0",
|
||||
maxDataCentreId));
|
||||
}
|
||||
|
||||
this.startEpoch = startEpoch;
|
||||
this.workerId = workerId;
|
||||
this.dataCentreId = dataCentreId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the next unique ID.
|
||||
*
|
||||
* @return the generated unique ID
|
||||
* @throws TimingException if the system clock moves backwards, indicating an invalid sequence
|
||||
* of timestamps.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Long nextId() {
|
||||
var timestamp = currentTimestamp();
|
||||
|
||||
// if the current time is less than the timestamp of the last ID generation, it means that
|
||||
// the system clock has been set back and an exception should be thrown
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new TimingException("Clock moved backwards. Refusing to generate id for %d milliseconds"
|
||||
.formatted(lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
// if generated at the same time, perform intra-millisecond sequences
|
||||
long sequenceBits = 12L;
|
||||
if (lastTimestamp == timestamp) {
|
||||
long sequenceMask = ~(-1L << sequenceBits);
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
// sequence overflow in milliseconds
|
||||
if (sequence == 0) {
|
||||
// block to the next millisecond, get a new timestamp
|
||||
timestamp = awaitToNextMillis(lastTimestamp);
|
||||
}
|
||||
}
|
||||
// timestamp change, sequence reset in milliseconds
|
||||
else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
// timestamp of last ID generation
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
// shifted and put together by or operations to form a 64-bit ID
|
||||
var timestampLeftShift = sequenceBits + workerIdBits + dataCentreIdBits;
|
||||
var dataCentreIdShift = sequenceBits + workerIdBits;
|
||||
return ((timestamp - startEpoch) << timestampLeftShift)
|
||||
| (dataCentreId << dataCentreIdShift)
|
||||
| (workerId << sequenceBits)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until the next millisecond to obtain a new timestamp.
|
||||
*
|
||||
* @param lastTimestamp the timestamp when the last ID was generated
|
||||
* @return the current timestamp
|
||||
*/
|
||||
private long awaitToNextMillis(long lastTimestamp) {
|
||||
var timestamp = currentTimestamp();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = currentTimestamp();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current timestamp in milliseconds.
|
||||
*
|
||||
* @return the current timestamp
|
||||
*/
|
||||
private long currentTimestamp() {
|
||||
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default custom epoch.
|
||||
*
|
||||
@@ -200,5 +93,116 @@ public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long>
|
||||
*/
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
/**
|
||||
* Constructs a SnowflakeGuidGenerator with the default start epoch and custom worker ID, data
|
||||
* centre ID.
|
||||
*
|
||||
* @param dataCentreId the data centre ID (between 0 and 31)
|
||||
* @param workerId the worker ID (between 0 and 31)
|
||||
*/
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId) {
|
||||
this(dataCentreId, workerId, DEFAULT_CUSTOM_EPOCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SnowflakeGuidGenerator with a custom epoch, worker ID, and data centre ID.
|
||||
*
|
||||
* @param dataCentreId the data centre ID (between 0 and 31)
|
||||
* @param workerId the worker ID (between 0 and 31)
|
||||
* @param startEpoch the custom epoch timestamp (in milliseconds) to start generating IDs from
|
||||
* @throws IllegalArgumentException if the start epoch is greater than the current timestamp,
|
||||
* or if the worker ID or data centre ID is out of range
|
||||
*/
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId, long startEpoch) {
|
||||
if (startEpoch > currentTimestamp()) {
|
||||
throw new IllegalArgumentException("Start Epoch can not be greater than current timestamp!");
|
||||
}
|
||||
|
||||
var maxWorkerId = ~(-1L << workerIdBits);
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("Worker Id can't be greater than %d or less than 0",
|
||||
maxWorkerId));
|
||||
}
|
||||
|
||||
var maxDataCentreId = ~(-1L << dataCentreIdBits);
|
||||
if (dataCentreId > maxDataCentreId || dataCentreId < 0) {
|
||||
throw new IllegalArgumentException(String.format("Data Centre Id can't be greater than %d or less than 0",
|
||||
maxDataCentreId));
|
||||
}
|
||||
|
||||
this.startEpoch = startEpoch;
|
||||
this.workerId = workerId;
|
||||
this.dataCentreId = dataCentreId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the next unique ID.
|
||||
*
|
||||
* @return the generated unique ID
|
||||
* @throws TimingException if the system clock moves backwards, indicating an invalid sequence
|
||||
* of timestamps.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Long nextId() {
|
||||
var timestamp = currentTimestamp();
|
||||
|
||||
// if the current time is less than the timestamp of the last ID generation, it means that
|
||||
// the system clock has been set back and an exception should be thrown
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new TimingException("Clock moved backwards. Refusing to generate id for %d milliseconds"
|
||||
.formatted(lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
// if generated at the same time, perform intra-millisecond sequences
|
||||
long sequenceBits = 12L;
|
||||
if (lastTimestamp == timestamp) {
|
||||
long sequenceMask = ~(-1L << sequenceBits);
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
// sequence overflow in milliseconds
|
||||
if (sequence == 0) {
|
||||
// block to the next millisecond, get a new timestamp
|
||||
timestamp = awaitToNextMillis(lastTimestamp);
|
||||
}
|
||||
}
|
||||
// timestamp change, sequence reset in milliseconds
|
||||
else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
// timestamp of last ID generation
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
// shifted and put together by or operations to form a 64-bit ID
|
||||
var timestampLeftShift = sequenceBits + workerIdBits + dataCentreIdBits;
|
||||
var dataCentreIdShift = sequenceBits + workerIdBits;
|
||||
return ((timestamp - startEpoch) << timestampLeftShift)
|
||||
| (dataCentreId << dataCentreIdShift)
|
||||
| (workerId << sequenceBits)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until the next millisecond to obtain a new timestamp.
|
||||
*
|
||||
* @param lastTimestamp the timestamp when the last ID was generated
|
||||
* @return the current timestamp
|
||||
*/
|
||||
private long awaitToNextMillis(long lastTimestamp) {
|
||||
var timestamp = currentTimestamp();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = currentTimestamp();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current timestamp in milliseconds.
|
||||
*
|
||||
* @return the current timestamp
|
||||
*/
|
||||
private long currentTimestamp() {
|
||||
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2024-2025 OnixByte.
|
||||
~ Copyright (c) 2024-2025 OnixByte
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
-->
|
||||
<configuration>
|
||||
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
|
||||
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
|
||||
|
||||
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
|
||||
<configuration>
|
||||
<property name="COLOURFUL_OUTPUT"
|
||||
value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
|
||||
<property name="STANDARD_OUTPUT"
|
||||
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
|
||||
|
||||
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>${COLOURFUL_OUTPUT}</pattern>
|
||||
@@ -28,4 +36,4 @@
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
Reference in New Issue
Block a user