diff --git a/.github/codeql/config.yml b/.github/codeql/config.yml new file mode 100644 index 0000000..9fa7243 --- /dev/null +++ b/.github/codeql/config.yml @@ -0,0 +1,18 @@ +name: "CodeQL Config" + +queries: + - uses: security-and-quality + +query-filters: + - exclude: + id: java/jdk-internal-api-access + - exclude: + id: java/missing-override-annotation + - exclude: + id: java/unused-parameter + - exclude: + id: java/confusing-method-signature + - exclude: + id: java/uncaught-number-format-exception + - exclude: + id: java/local-shadows-field \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 802a47e..eea74d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,22 +22,23 @@ jobs: os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ] steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Cache gradle dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle') }} restore-keys: | ${{ runner.os }}-gradle-caches- - name: Cache gradle wrapper - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.gradle/wrapper key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} - name: Setup java - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'zulu' java-version: ${{ matrix.java }} - name: Build with gradle run: ./gradlew build \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..80a3a9d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,35 @@ +name: "CodeQL" + +on: + workflow_dispatch: + push: + branches: ['main', 'release-*'] + pull_request: + types: [opened, synchronize] + branches: ['main', 'release-*'] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: java + queries: +security-and-quality + config-file: ./.github/codeql/config.yml + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:java" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d69d92b..6c1683a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Prepare branch run: | git config user.name github-actions @@ -42,7 +42,7 @@ jobs: os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ] steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout branch (Windows) if: matrix.os == 'windows-latest' run: | @@ -58,8 +58,9 @@ jobs: git fetch git checkout -b workflow-$GITHUB_RUN_ID origin/workflow-$GITHUB_RUN_ID~1 - name: Setup java - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'zulu' java-version: ${{ matrix.java }} - name: Build with gradle run: ./gradlew build @@ -71,7 +72,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Release branch run: | git config user.name github-actions @@ -91,7 +92,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout branch run: | git config user.name github-actions @@ -99,8 +100,9 @@ jobs: git fetch git checkout -b workflow-$GITHUB_RUN_ID origin/workflow-$GITHUB_RUN_ID~1 - name: Setup java - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'zulu' java-version: 8 - name: Publish jars run: ./gradlew publishAll @@ -118,7 +120,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Cleanup run: | git config user.name github-actions diff --git a/README.md b/README.md index 76b070e..f81b99c 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,7 @@ ![Maven Central](https://img.shields.io/maven-central/v/com.epam.deltix/gflog-api) ![Continuous Integration](https://github.com/epam/GFLog/workflows/Continuous%20Integration/badge.svg?branch=main) -[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/epam/GFLog.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/epam/GFLog/context:java) -[![Total alerts](https://img.shields.io/lgtm/alerts/g/epam/GFLog.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/epam/GFLog/alerts/) +![CodeQL](https://github.com/epam/GFLog/workflows/CodeQL/badge.svg?branch=main) Highly efficient garbage-free logging framework for Java 8+. diff --git a/gflog-api/src/main/java/com/epam/deltix/gflog/api/AppendableEntry.java b/gflog-api/src/main/java/com/epam/deltix/gflog/api/AppendableEntry.java index 218ce53..3bffe0c 100644 --- a/gflog-api/src/main/java/com/epam/deltix/gflog/api/AppendableEntry.java +++ b/gflog-api/src/main/java/com/epam/deltix/gflog/api/AppendableEntry.java @@ -128,6 +128,14 @@ public interface AppendableEntry extends Appendable { */ AppendableEntry appendTimestamp(final long timestamp); + /** + * Appends the timestamp in nanoseconds since Epoch in "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + AppendableEntry appendTimestampNs(final long timestampNs); + /** * Appends the date part of the timestamp in milliseconds since Epoch in "yyyy-MM-dd" format to this entry. * @@ -136,6 +144,14 @@ public interface AppendableEntry extends Appendable { */ AppendableEntry appendDate(final long timestamp); + /** + * Appends the date part of the timestamp in nanoseconds since Epoch in "yyyy-MM-dd" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + AppendableEntry appendDateNs(final long timestampNs); + /** * Appends the time part of the timestamp in milliseconds since Epoch in "HH:mm:ss.SSS" format to this entry. * @@ -144,6 +160,14 @@ public interface AppendableEntry extends Appendable { */ AppendableEntry appendTime(final long timestamp); + /** + * Appends the time part of the timestamp in nanoseconds since Epoch in "HH:mm:ss.SSSSSSSSS" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + AppendableEntry appendTimeNs(final long timestampNs); + /** * Appends the alphanumeric value to this entry. * diff --git a/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntry.java b/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntry.java index 09f2c71..586a3dd 100644 --- a/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntry.java +++ b/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntry.java @@ -145,6 +145,15 @@ public interface LogEntry extends AppendableEntry { @CheckReturnValue LogEntry appendTimestamp(final long timestamp); + /** + * Appends the timestamp in nanoseconds since Epoch in "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + @CheckReturnValue + LogEntry appendTimestampNs(final long timestampNs); + /** * Appends the date part of the timestamp in milliseconds since Epoch in "yyyy-MM-dd" format to this entry. * @@ -154,6 +163,15 @@ public interface LogEntry extends AppendableEntry { @CheckReturnValue LogEntry appendDate(final long timestamp); + /** + * Appends the date part of the timestamp in nanoseconds since Epoch in "yyyy-MM-dd" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + @CheckReturnValue + LogEntry appendDateNs(final long timestampNs); + /** * Appends the time part of the timestamp in milliseconds since Epoch in "HH:mm:ss.SSS" format to this entry. * @@ -163,6 +181,15 @@ public interface LogEntry extends AppendableEntry { @CheckReturnValue LogEntry appendTime(final long timestamp); + /** + * Appends the time part of the timestamp in nanoseconds since Epoch in "HH:mm:ss.SSSSSSSSS" format to this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + * @return a reference to this object. + */ + @CheckReturnValue + LogEntry appendTimeNs(final long timestampNs); + /** * Appends the alphanumeric value to this entry. * @@ -299,14 +326,29 @@ public interface LogEntry extends AppendableEntry { void appendTimestampLast(final long timestamp); /** - * Appends the date part of the timestamp in milliseconds since Epoch in "yyyy-MM-dd" format to this entry. - * Commits this entry. + * Appends the timestamp in nanoseconds since Epoch in "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'" format to this entry. * Commits this entry. * + * @param timestampNs in nanoseconds since Epoch to append. + */ + void appendTimestampNsLast(final long timestampNs); + + /** + * Appends the date part of the timestamp in milliseconds since Epoch in "yyyy-MM-dd" format to this entry. + * Commits this entry. + * * @param timestamp in milliseconds since Epoch to append. */ void appendDateLast(final long timestamp); + /** + * Appends the date part of the timestamp in nanoseconds since Epoch in "yyyy-MM-dd" format to this entry. + * Commits this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + */ + void appendDateNsLast(final long timestampNs); + /** * Appends the time part of the timestamp in milliseconds since Epoch in "HH:mm:ss.SSS" format to this entry. * Commits this entry. @@ -315,6 +357,14 @@ public interface LogEntry extends AppendableEntry { */ void appendTimeLast(final long timestamp); + /** + * Appends the time part of the timestamp in nanoseconds since Epoch in "HH:mm:ss.SSSSSSSSS" format to this entry. + * Commits this entry. + * + * @param timestampNs in nanoseconds since Epoch to append. + */ + void appendTimeNsLast(final long timestampNs); + /** * Appends the alphanumeric value to this entry. * Commits this entry. @@ -323,7 +373,6 @@ public interface LogEntry extends AppendableEntry { */ void appendAlphanumericLast(final long alphanumeric); - /** * Aborts this entry. Clears its content after. */ diff --git a/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntryTemplate.java b/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntryTemplate.java index 70a3bf1..2cfe09e 100644 --- a/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntryTemplate.java +++ b/gflog-api/src/main/java/com/epam/deltix/gflog/api/LogEntryTemplate.java @@ -128,6 +128,14 @@ public interface LogEntryTemplate { */ LogEntryTemplate withTimestamp(final long timestamp); + /** + * Inserts the timestamp in nanoseconds since Epoch in "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'" format to this template. + * + * @param timestampNs in nanoseconds since Epoch to insert. + * @return a reference to this object. + */ + LogEntryTemplate withTimestampNs(final long timestampNs); + /** * Inserts the date part of the timestamp in milliseconds since Epoch in "yyyy-MM-dd" format to this template. * @@ -136,6 +144,14 @@ public interface LogEntryTemplate { */ LogEntryTemplate withDate(final long timestamp); + /** + * Inserts the date part of the timestamp in nanoseconds since Epoch in "yyyy-MM-dd" format to this template. + * + * @param timestampNs in nanoseconds since Epoch to insert. + * @return a reference to this object. + */ + LogEntryTemplate withDateNs(final long timestampNs); + /** * Inserts the time part of the timestamp in milliseconds since Epoch in "HH:mm:ss.SSS" format to this template. * @@ -144,6 +160,14 @@ public interface LogEntryTemplate { */ LogEntryTemplate withTime(final long timestamp); + /** + * Inserts the time part of the timestamp in nanoseconds since Epoch in "HH:mm:ss.SSSSSSSSS" format to this template. + * + * @param timestampNs in nanoseconds since Epoch to insert. + * @return a reference to this object. + */ + LogEntryTemplate withTimeNs(final long timestampNs); + /** * Inserts the alphanumeric value to this template. * diff --git a/gflog-api/src/main/java/com/epam/deltix/gflog/api/NoOpLogEntry.java b/gflog-api/src/main/java/com/epam/deltix/gflog/api/NoOpLogEntry.java index af5c367..005b593 100644 --- a/gflog-api/src/main/java/com/epam/deltix/gflog/api/NoOpLogEntry.java +++ b/gflog-api/src/main/java/com/epam/deltix/gflog/api/NoOpLogEntry.java @@ -83,16 +83,31 @@ public NoOpLogEntry appendTimestamp(final long timestamp) { return this; } + @Override + public LogEntry appendTimestampNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry appendDate(final long timestamp) { return this; } + @Override + public LogEntry appendDateNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry appendTime(final long timestamp) { return this; } + @Override + public LogEntry appendTimeNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry appendAlphanumeric(final long alphanumeric) { return this; @@ -158,14 +173,26 @@ public void appendDecimal64Last(final long decimal) { public void appendTimestampLast(final long timestamp) { } + @Override + public void appendTimestampNsLast(long timestampNs) { + } + @Override public void appendDateLast(final long timestamp) { } + @Override + public void appendDateNsLast(long timestampNs) { + } + @Override public void appendTimeLast(final long timestamp) { } + @Override + public void appendTimeNsLast(long timestampNs) { + } + @Override public void appendAlphanumericLast(final long alphanumeric) { } @@ -253,16 +280,31 @@ public NoOpLogEntry withTimestamp(final long timestamp) { return this; } + @Override + public LogEntryTemplate withTimestampNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry withDate(final long timestamp) { return this; } + @Override + public LogEntryTemplate withDateNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry withTime(final long timestamp) { return this; } + @Override + public LogEntryTemplate withTimeNs(long timestampNs) { + return this; + } + @Override public NoOpLogEntry withAlphanumeric(final long alphanumeric) { return this; diff --git a/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/log4j/Log4jBenchmarkUtil.java b/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/log4j/Log4jBenchmarkUtil.java index cc22767..5975141 100644 --- a/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/log4j/Log4jBenchmarkUtil.java +++ b/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/log4j/Log4jBenchmarkUtil.java @@ -5,6 +5,8 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.spi.LoggerContext; +import java.util.Objects; + import static com.epam.deltix.gflog.benchmark.util.BenchmarkUtil.*; import static org.apache.logging.log4j.util.Unbox.box; @@ -23,6 +25,7 @@ public static void prepare(final String config) { deleteTempDirectory(); final Logger lazy = getLogger(); // forces lazy initialization + Objects.requireNonNull(lazy); } public static void cleanup() { diff --git a/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/util/BenchmarkState.java b/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/util/BenchmarkState.java index c50a33a..2f51b72 100644 --- a/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/util/BenchmarkState.java +++ b/gflog-benchmark/src/main/java/com/epam/deltix/gflog/benchmark/util/BenchmarkState.java @@ -94,7 +94,7 @@ private static Throwable newExceptionWithoutStack(final int depth) { return new Throwable("my-exception-without-stack") { @Override - public Throwable fillInStackTrace() { // lgtm [java/non-sync-override] + public Throwable fillInStackTrace() { //lgtm return this; // false positive } @@ -108,21 +108,21 @@ public Throwable fillInStackTrace() { // lgtm [java/non-sync-override] public class BenchmarkState extends BenchmarkStateFields { - byte p000, p001, p002, p003, p004, p005, p006, p007, p008, p009, p010, p011, p012, p013, p014, p015; - byte p016, p017, p018, p019, p020, p021, p022, p023, p024, p025, p026, p027, p028, p029, p030, p031; - byte p032, p033, p034, p035, p036, p037, p038, p039, p040, p041, p042, p043, p044, p045, p046, p047; - byte p048, p049, p050, p051, p052, p053, p054, p055, p056, p057, p058, p059, p060, p061, p062, p063; - byte p064, p065, p066, p067, p068, p069, p070, p071, p072, p073, p074, p075, p076, p077, p078, p079; - byte p080, p081, p082, p083, p084, p085, p086, p087, p088, p089, p090, p091, p092, p093, p094, p095; - byte p096, p097, p098, p099, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111; - byte p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127; - byte p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143; - byte p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159; - byte p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175; - byte p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191; - byte p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207; - byte p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223; - byte p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239; - byte p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251, p252, p253, p254, p255; + byte p256, p257, p258, p259, p260, p261, p262, p263, p264, p265, p266, p267, p268, p269, p270, p271; + byte p272, p273, p274, p275, p276, p277, p278, p279, p280, p281, p282, p283, p284, p285, p286, p287; + byte p288, p289, p290, p291, p292, p293, p294, p295, p296, p297, p298, p299, p300, p301, p302, p303; + byte p304, p305, p306, p307, p308, p309, p310, p311, p312, p313, p314, p315, p316, p317, p318, p319; + byte p320, p321, p322, p323, p324, p325, p326, p327, p328, p329, p330, p331, p332, p333, p334, p335; + byte p336, p337, p338, p339, p340, p341, p342, p343, p344, p345, p346, p347, p348, p349, p350, p351; + byte p352, p353, p354, p355, p356, p357, p358, p359, p360, p361, p362, p363, p364, p365, p366, p367; + byte p368, p369, p370, p371, p372, p373, p374, p375, p376, p377, p378, p379, p380, p381, p382, p383; + byte p384, p385, p386, p387, p388, p389, p390, p391, p392, p393, p394, p395, p396, p397, p398, p399; + byte p400, p401, p402, p403, p404, p405, p406, p407, p408, p409, p410, p411, p412, p413, p414, p415; + byte p416, p417, p418, p419, p420, p421, p422, p423, p424, p425, p426, p427, p428, p429, p430, p431; + byte p432, p433, p434, p435, p436, p437, p438, p439, p440, p441, p442, p443, p444, p445, p446, p447; + byte p448, p449, p450, p451, p452, p453, p454, p455, p456, p457, p458, p459, p460, p461, p462, p463; + byte p464, p465, p466, p467, p468, p469, p470, p471, p472, p473, p474, p475, p476, p477, p478, p479; + byte p480, p481, p482, p483, p484, p485, p486, p487, p488, p489, p490, p491, p492, p493, p494, p495; + byte p496, p497, p498, p499, p500, p501, p502, p503, p504, p505, p506, p507, p508, p509, p510, p511; } diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/LogConfigFactory.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/LogConfigFactory.java index 392a0f3..1297872 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/LogConfigFactory.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/LogConfigFactory.java @@ -12,6 +12,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; @@ -223,7 +224,7 @@ public static LogConfig load(final InputStream stream, final Properties properti factory.setNamespaceAware(true); final DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setErrorHandler(ErrorHandler.INSTANCE); + builder.setErrorHandler(ParsingErrorHandler.INSTANCE); final Document document = builder.parse(substitution); return getConfig(document); @@ -251,7 +252,7 @@ private static InputStream substitute(final InputStream stream, final Properties final String original = new String(array, 0, length, StandardCharsets.UTF_8); final String substitution = PropertyUtil.substitute(original, properties); - return (original == substitution) ? + return original.equals(substitution) ? new ByteArrayInputStream(array, 0, length) : new ByteArrayInputStream(substitution.getBytes(StandardCharsets.UTF_8)); } @@ -502,22 +503,22 @@ private static class AttributeConversionException extends SAXException { } - private static class ErrorHandler implements org.xml.sax.ErrorHandler { + private static class ParsingErrorHandler implements ErrorHandler { - private static final ErrorHandler INSTANCE = new ErrorHandler(); + private static final ParsingErrorHandler INSTANCE = new ParsingErrorHandler(); @Override - public void warning(final SAXParseException exception) throws SAXException { + public void warning(final SAXParseException exception) { LogDebug.warn(exception.getMessage()); } @Override - public void error(final SAXParseException exception) throws SAXException { + public void error(final SAXParseException exception) { LogDebug.warn(exception.getMessage()); } @Override - public void fatalError(final SAXParseException exception) throws SAXException { + public void fatalError(final SAXParseException exception) { LogDebug.warn(exception.getMessage()); } diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/idle/BackoffIdleStrategy.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/idle/BackoffIdleStrategy.java index 5559939..c7d0597 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/idle/BackoffIdleStrategy.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/idle/BackoffIdleStrategy.java @@ -5,7 +5,7 @@ import java.util.concurrent.locks.LockSupport; @SuppressWarnings("unused") -abstract class BackoffIdleStrategyLhs { +abstract class BackoffIdleStrategyPadding { byte b000, b001, b002, b003, b004, b005, b006, b007, b008, b009, b010, b011, b012, b013, b014, b015, b016, b017, b018, b019, b020, b021, b022, b023, b024, b025, b026, b027, b028, b029, b030, b031, b032, b033, b034, b035, b036, b037, b038, b039, b040, b041, b042, b043, b044, b045, b046, b047, @@ -16,7 +16,7 @@ abstract class BackoffIdleStrategyLhs { b112, b113, b114, b115, b116, b117, b118, b119, b120, b121, b122, b123, b124, b125, b126, b127; } -abstract class BackoffIdleStrategyData extends BackoffIdleStrategyLhs { +abstract class BackoffIdleStrategyData extends BackoffIdleStrategyPadding { static final int WORKING = 0; static final int SPINNING = 1; @@ -51,14 +51,14 @@ abstract class BackoffIdleStrategyData extends BackoffIdleStrategyLhs { @SuppressWarnings("unused") public final class BackoffIdleStrategy extends BackoffIdleStrategyData implements IdleStrategy { - byte b000, b001, b002, b003, b004, b005, b006, b007, b008, b009, b010, b011, b012, b013, b014, b015, - b016, b017, b018, b019, b020, b021, b022, b023, b024, b025, b026, b027, b028, b029, b030, b031, - b032, b033, b034, b035, b036, b037, b038, b039, b040, b041, b042, b043, b044, b045, b046, b047, - b048, b049, b050, b051, b052, b053, b054, b055, b056, b057, b058, b059, b060, b061, b062, b063, - b064, b065, b066, b067, b068, b069, b070, b071, b072, b073, b074, b075, b076, b077, b078, b079, - b080, b081, b082, b083, b084, b085, b086, b087, b088, b089, b090, b091, b092, b093, b094, b095, - b096, b097, b098, b099, b100, b101, b102, b103, b104, b105, b106, b107, b108, b109, b110, b111, - b112, b113, b114, b115, b116, b117, b118, b119, b120, b121, b122, b123, b124, b125, b126, b127; + byte b128, b129, b130, b131, b132, b133, b134, b135, b136, b137, b138, b139, b140, b141, b142, b143, + b144, b145, b146, b147, b148, b149, b150, b151, b152, b153, b154, b155, b156, b157, b158, b159, + b160, b161, b162, b163, b164, b165, b166, b167, b168, b169, b170, b171, b172, b173, b174, b175, + b176, b177, b178, b179, b180, b181, b182, b183, b184, b185, b186, b187, b188, b189, b190, b191, + b192, b193, b194, b195, b196, b197, b198, b199, b200, b201, b202, b203, b204, b205, b206, b207, + b208, b209, b210, b211, b212, b213, b214, b215, b216, b217, b218, b219, b220, b221, b222, b223, + b224, b225, b226, b227, b228, b229, b230, b231, b232, b233, b234, b235, b236, b237, b238, b239, + b240, b241, b242, b243, b244, b245, b246, b247, b248, b249, b250, b251, b252, b253, b254, b255; public BackoffIdleStrategy(final long maxSpins, final long maxYields, diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/layout/template/FastDateFormat.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/layout/template/FastDateFormat.java index 2ffbfc9..92c2088 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/layout/template/FastDateFormat.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/layout/template/FastDateFormat.java @@ -334,9 +334,9 @@ public boolean equals(final Object obj) { return false; } final FastDateFormat other = (FastDateFormat) obj; - return (mPattern == other.mPattern || mPattern.equals(other.mPattern)) && - (mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) && - (mLocale == other.mLocale || mLocale.equals(other.mLocale)) && + return Objects.equals(mPattern, other.mPattern) && + Objects.equals(mTimeZone, other.mTimeZone) && + Objects.equals(mLocale, other.mLocale) && (mTimeZoneForced == other.mTimeZoneForced) && (mLocaleForced == other.mLocaleForced); } diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLimitedEntry.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLimitedEntry.java index c4b496d..abd4094 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLimitedEntry.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLimitedEntry.java @@ -266,6 +266,23 @@ public final LogLimitedEntry appendTimestamp(final long timestamp) { return this; } + @Override + public final LogLimitedEntry appendTimestampNs(final long timestampNs) { + if (!truncated) { + if (timestampNs == Long.MIN_VALUE) { + formatNull(); + } else { + Formatting.verifyTimestampNs(timestampNs); + ensureSpace(LENGTH_OF_TIMESTAMP_NS); + length = Formatting.formatTimestampNs(timestampNs, array, length); + } + + verifyLimit(); + } + + return this; + } + @Override public final LogLimitedEntry appendDate(final long timestamp) { if (!truncated) { @@ -283,6 +300,23 @@ public final LogLimitedEntry appendDate(final long timestamp) { return this; } + @Override + public AppendableEntry appendDateNs(long timestampNs) { + if (!truncated) { + if (timestampNs == Long.MIN_VALUE) { + formatNull(); + } else { + Formatting.verifyTimestampNs(timestampNs); + ensureSpace(LENGTH_OF_DATE); + length = Formatting.formatDateNs(timestampNs, array, length); + } + + verifyLimit(); + } + + return this; + } + @Override public final LogLimitedEntry appendTime(final long timestamp) { if (!truncated) { @@ -300,6 +334,23 @@ public final LogLimitedEntry appendTime(final long timestamp) { return this; } + @Override + public AppendableEntry appendTimeNs(long timestampNs) { + if (!truncated) { + if (timestampNs == Long.MIN_VALUE) { + formatNull(); + } else { + Formatting.verifyTimestampNs(timestampNs); + ensureSpace(LENGTH_OF_TIME_NS); + length = Formatting.formatTimeNs(timestampNs, array, length); + } + + verifyLimit(); + } + + return this; + } + void appendUtf8Bytes(final Buffer bytes, final int bytesOffset, final int bytesLength) { if (!truncated) { if (bytes == null) { diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLocalEntry.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLocalEntry.java index 50d1e5f..bb43c2c 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLocalEntry.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/service/LogLocalEntry.java @@ -197,6 +197,15 @@ public LogLocalEntry appendTimestamp(final long timestamp) { return this; } + @Override + public LogEntry appendTimestampNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimestampNs(timestampNs); + } + + return this; + } + @Override public LogLocalEntry appendDate(final long timestamp) { if (verifyNotCommitted()) { @@ -206,6 +215,15 @@ public LogLocalEntry appendDate(final long timestamp) { return this; } + @Override + public LogEntry appendDateNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendDateNs(timestampNs); + } + + return this; + } + @Override public LogLocalEntry appendTime(final long timestamp) { if (verifyNotCommitted()) { @@ -215,6 +233,15 @@ public LogLocalEntry appendTime(final long timestamp) { return this; } + @Override + public LogEntry appendTimeNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimeNs(timestampNs); + } + + return this; + } + @Override public LogLocalEntry appendAlphanumeric(final long alphanumeric) { if (verifyNotCommitted()) { @@ -349,6 +376,14 @@ private void doAppendTimestamp(final long timestamp) { } } + private void doAppendTimestampNs(final long timestampNs) { + try { + entry.appendTimestampNs(timestampNs); + } catch (final Throwable e) { + warnAppendError(e); + } + } + private void doAppendDate(final long timestamp) { try { entry.appendDate(timestamp); @@ -357,6 +392,14 @@ private void doAppendDate(final long timestamp) { } } + private void doAppendDateNs(final long timestampNs) { + try { + entry.appendDateNs(timestampNs); + } catch (final Throwable e) { + warnAppendError(e); + } + } + private void doAppendTime(final long timestamp) { try { entry.appendTime(timestamp); @@ -365,6 +408,14 @@ private void doAppendTime(final long timestamp) { } } + private void doAppendTimeNs(final long timestampNs) { + try { + entry.appendTimeNs(timestampNs); + } catch (final Throwable e) { + warnAppendError(e); + } + } + private void doAppendAlphanumeric(final long alphanumeric) { try { entry.appendAlphanumeric(alphanumeric); @@ -497,6 +548,14 @@ public void appendTimestampLast(final long timestamp) { } } + @Override + public void appendTimestampNsLast(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimestampNs(timestampNs); + doCommit(); + } + } + @Override public void appendDateLast(final long timestamp) { if (verifyNotCommitted()) { @@ -505,6 +564,14 @@ public void appendDateLast(final long timestamp) { } } + @Override + public void appendDateNsLast(long timestampNs) { + if (verifyNotCommitted()) { + doAppendDateNs(timestampNs); + doCommit(); + } + } + @Override public void appendTimeLast(final long timestamp) { if (verifyNotCommitted()) { @@ -513,6 +580,14 @@ public void appendTimeLast(final long timestamp) { } } + @Override + public void appendTimeNsLast(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimeNs(timestampNs); + doCommit(); + } + } + @Override public void appendAlphanumericLast(final long alphanumeric) { if (verifyNotCommitted()) { @@ -720,6 +795,19 @@ public LogLocalEntry withTimestamp(final long timestamp) { return this; } + @Override + public LogEntryTemplate withTimestampNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimestampNs(timestampNs); + + if (doAppendTemplate()) { + doCommit(); + } + } + + return this; + } + @Override public LogLocalEntry withDate(final long timestamp) { if (verifyNotCommitted()) { @@ -733,6 +821,19 @@ public LogLocalEntry withDate(final long timestamp) { return this; } + @Override + public LogEntryTemplate withDateNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendDateNs(timestampNs); + + if (doAppendTemplate()) { + doCommit(); + } + } + + return this; + } + @Override public LogLocalEntry withTime(final long timestamp) { if (verifyNotCommitted()) { @@ -746,6 +847,19 @@ public LogLocalEntry withTime(final long timestamp) { return this; } + @Override + public LogEntryTemplate withTimeNs(long timestampNs) { + if (verifyNotCommitted()) { + doAppendTimeNs(timestampNs); + + if (doAppendTemplate()) { + doCommit(); + } + } + + return this; + } + @Override public LogLocalEntry withAlphanumeric(final long alphanumeric) { if (verifyNotCommitted()) { diff --git a/gflog-core/src/main/java/com/epam/deltix/gflog/core/util/Formatting.java b/gflog-core/src/main/java/com/epam/deltix/gflog/core/util/Formatting.java index 7f39684..95546ea 100644 --- a/gflog-core/src/main/java/com/epam/deltix/gflog/core/util/Formatting.java +++ b/gflog-core/src/main/java/com/epam/deltix/gflog/core/util/Formatting.java @@ -18,8 +18,10 @@ public final class Formatting { public static final int LENGTH_OF_TRUE = 4; public static final int LENGTH_OF_FALSE = 5; public static final int LENGTH_OF_TIMESTAMP = 24; + public static final int LENGTH_OF_TIMESTAMP_NS = 30; public static final int LENGTH_OF_DATE = 10; public static final int LENGTH_OF_TIME = 12; + public static final int LENGTH_OF_TIME_NS = 18; public static final int MAX_LENGTH_OF_BOOLEAN = 5; public static final int MAX_LENGTH_OF_ALPHANUMERIC = 10; diff --git a/gflog-core/src/test/java/com/epam/deltix/gflog/TestUtil.java b/gflog-core/src/test/java/com/epam/deltix/gflog/TestUtil.java index 9789220..c8c6ff0 100644 --- a/gflog-core/src/test/java/com/epam/deltix/gflog/TestUtil.java +++ b/gflog-core/src/test/java/com/epam/deltix/gflog/TestUtil.java @@ -1,5 +1,7 @@ package com.epam.deltix.gflog; +import com.epam.deltix.gflog.core.util.Formatting; + import java.math.BigDecimal; import java.time.Instant; import java.time.ZoneId; @@ -11,8 +13,10 @@ public class TestUtil { protected static final ZoneId UTC_ZONE = ZoneId.of("UTC"); protected static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS'Z'"); + protected static final DateTimeFormatter TIMESTAMP_NS_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'"); protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd"); protected static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); + protected static final DateTimeFormatter TIME_NS_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSSSS"); private static final int[] INT_RANGE = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Integer.MAX_VALUE}; @@ -32,9 +36,13 @@ public static long randomDecimal64() { return Decimal64Util.parse(value); } - public static long randomTimestamp() { - final long timestamp = random().nextLong(-1000, 3153600000000L); + final long timestamp = random().nextLong(-1000, Formatting.MAX_VALUE_OF_TIMESTAMP); + return (timestamp < 0) ? Long.MIN_VALUE : timestamp; + } + + public static long randomTimestampNs() { + final long timestamp = random().nextLong(-1000, Formatting.MAX_VALUE_OF_TIMESTAMP_NS); return (timestamp < 0) ? Long.MIN_VALUE : timestamp; } @@ -186,14 +194,26 @@ public static String formatTimestamp(long timestamp) { return Instant.ofEpochMilli(timestamp).atZone(UTC_ZONE).format(TIMESTAMP_FORMATTER); } + public static String formatTimestampNs(long timestampNs) { + return Instant.ofEpochSecond(0, timestampNs).atZone(UTC_ZONE).format(TIMESTAMP_NS_FORMATTER); + } + public static String formatDate(long timestamp) { return Instant.ofEpochMilli(timestamp).atZone(UTC_ZONE).format(DATE_FORMATTER); } + public static String formatDateNs(long timestampNs) { + return Instant.ofEpochSecond(0, timestampNs).atZone(UTC_ZONE).format(DATE_FORMATTER); + } + public static String formatTime(long timestamp) { return Instant.ofEpochMilli(timestamp).atZone(UTC_ZONE).format(TIME_FORMATTER); } + public static String formatTimeNs(long timestampNs) { + return Instant.ofEpochSecond(0, timestampNs).atZone(UTC_ZONE).format(TIME_NS_FORMATTER); + } + public static String formatAlphanumeric(long value) { if (value == Long.MIN_VALUE) { return "null"; diff --git a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogAsciiEntryFormattingTest.java b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogAsciiEntryFormattingTest.java index 2ab3dfe..1c929c3 100644 --- a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogAsciiEntryFormattingTest.java +++ b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogAsciiEntryFormattingTest.java @@ -83,6 +83,7 @@ public void testRandomValues() { final long longValue = TestUtil.randomLongWithLength(1, 19); final long timestampValue = TestUtil.randomTimestamp(); + final long timestampNsValue = TestUtil.randomTimestampNs(); final long alphanumericValue = TestUtil.randomAlphanumeric(-1, 10); final int precision = TestUtil.randomInt(0, 9); @@ -96,8 +97,11 @@ public void testRandomValues() { .append(", int=").append(intValue) .append(", long=").append(longValue) .append(", timestamp=").append(TestUtil.formatTimestamp(timestampValue)) + .append(", timestampNs=").append(TestUtil.formatTimestampNs(timestampNsValue)) .append(", date=").append(TestUtil.formatDate(timestampValue)) + .append(", dateNs=").append(TestUtil.formatDateNs(timestampNsValue)) .append(", time=").append(TestUtil.formatTime(timestampValue)) + .append(", timeNs=").append(TestUtil.formatTimeNs(timestampNsValue)) .append(", alphanumeric=").append(TestUtil.formatAlphanumeric(alphanumericValue)) .append(", double=").append(i) .append(", doubleWithPrecision=").append(formatDouble(i, precision)) @@ -113,8 +117,11 @@ public void testRandomValues() { .append(", int=").append(intValue) .append(", long=").append(longValue) .append(", timestamp=").appendTimestamp(timestampValue) + .append(", timestampNs=").appendTimestampNs(timestampNsValue) .append(", date=").appendDate(timestampValue) + .append(", dateNs=").appendDateNs(timestampNsValue) .append(", time=").appendTime(timestampValue) + .append(", timeNs=").appendTimeNs(timestampNsValue) .append(", alphanumeric=").appendAlphanumeric(alphanumericValue) .append(", double=").append(i) .append(", doubleWithPrecision=").append(i, precision) diff --git a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogBufferTest.java b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogBufferTest.java index 1525811..9ee3c96 100644 --- a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogBufferTest.java +++ b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogBufferTest.java @@ -63,7 +63,7 @@ public void producersShouldNotBlock() throws Exception { final LogBuffer.RecordHandler handler = (buffer, offset, length) -> { Assert.assertTrue(offset >= 0); Assert.assertTrue(length >= 0); - Assert.assertTrue(offset + length >= 0); + Assert.assertTrue(Integer.MAX_VALUE - offset - length >= 0); }; final long deadline = System.currentTimeMillis() + 1000; diff --git a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogUtf8EntryFormattingTest.java b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogUtf8EntryFormattingTest.java index 5fd9809..b8ed319 100644 --- a/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogUtf8EntryFormattingTest.java +++ b/gflog-core/src/test/java/com/epam/deltix/gflog/core/service/LogUtf8EntryFormattingTest.java @@ -83,6 +83,7 @@ public void testRandomValues() { final long longValue = TestUtil.randomLongWithLength(1, 19); final long timestampValue = TestUtil.randomTimestamp(); + final long timestampNsValue = TestUtil.randomTimestampNs(); final long alphanumericValue = TestUtil.randomAlphanumeric(-1, 10); final int precision = TestUtil.randomInt(0, 9); @@ -96,8 +97,11 @@ public void testRandomValues() { .append(", int=").append(intValue) .append(", long=").append(longValue) .append(", timestamp=").append(TestUtil.formatTimestamp(timestampValue)) + .append(", timestampNs=").append(TestUtil.formatTimestampNs(timestampNsValue)) .append(", date=").append(TestUtil.formatDate(timestampValue)) + .append(", dateNs=").append(TestUtil.formatDateNs(timestampNsValue)) .append(", time=").append(TestUtil.formatTime(timestampValue)) + .append(", timeNs=").append(TestUtil.formatTimeNs(timestampNsValue)) .append(", alphanumeric=").append(TestUtil.formatAlphanumeric(alphanumericValue)) .append(", double=").append(i) .append(", doubleWithPrecision=").append(formatDouble(i, precision)) @@ -113,8 +117,11 @@ public void testRandomValues() { .append(", int=").append(intValue) .append(", long=").append(longValue) .append(", timestamp=").appendTimestamp(timestampValue) + .append(", timestampNs=").appendTimestampNs(timestampNsValue) .append(", date=").appendDate(timestampValue) + .append(", dateNs=").appendDateNs(timestampNsValue) .append(", time=").appendTime(timestampValue) + .append(", timeNs=").appendTimeNs(timestampNsValue) .append(", alphanumeric=").appendAlphanumeric(alphanumericValue) .append(", double=").append(i) .append(", doubleWithPrecision=").append(i, precision) diff --git a/gflog-jul/src/main/java/com/epam/deltix/gflog/jul/JulBridgeLogger.java b/gflog-jul/src/main/java/com/epam/deltix/gflog/jul/JulBridgeLogger.java index a5874a8..9d4a708 100644 --- a/gflog-jul/src/main/java/com/epam/deltix/gflog/jul/JulBridgeLogger.java +++ b/gflog-jul/src/main/java/com/epam/deltix/gflog/jul/JulBridgeLogger.java @@ -225,7 +225,7 @@ private static void appendMessageWithParams(final String message, final Object[] searchFrom = end + 1; final int index = getIndex(message, start + 1, end); - if (index < 0 | index >= params.length) { + if (index < 0 || index >= params.length) { continue; } diff --git a/gflog-slf4j/src/test/java/com/epam/deltix/gflog/slf4j/Slf4jBridgeTest.java b/gflog-slf4j/src/test/java/com/epam/deltix/gflog/slf4j/Slf4jBridgeTest.java index 34f894d..b5ce375 100644 --- a/gflog-slf4j/src/test/java/com/epam/deltix/gflog/slf4j/Slf4jBridgeTest.java +++ b/gflog-slf4j/src/test/java/com/epam/deltix/gflog/slf4j/Slf4jBridgeTest.java @@ -17,7 +17,7 @@ public void test() { log.info("{}", "3"); log.info("--{}--", "4"); - log.info("--{}--", "5", "6"); // lgtm [java/unused-format-argument] + log.info("--{}--", "5", "6"); //lgtm log.info("--{}--", "6", new IllegalArgumentException()); log.info("--{}", "7", new IllegalArgumentException());