From 65e93bf6cc8d63e1992689adde5145797870db34 Mon Sep 17 00:00:00 2001 From: Oliver Siegmar Date: Sun, 23 Aug 2020 09:41:00 +0200 Subject: [PATCH] Removed MD5 for creating Message-IDs and rewrote MessageIdSupplier logic (#52) --- CHANGELOG.md | 4 ++ .../siegmar/logbackgelf/GelfUdpChunker.java | 8 +-- .../logbackgelf/MessageIdSupplier.java | 54 +++++-------------- .../logbackgelf/MessageIdSupplierTest.java | 13 ++--- 4 files changed, 26 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d65a299..ebb21d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add poolMaxIdleTime configuration option to TCP appenders [\#49](https://github.com/osiegmar/logback-gelf/pull/49) +### Changed +- Removed MD5 for creating Message-IDs and rewrote MessageIdSupplier logic (#52) + [\#52](https://github.com/osiegmar/logback-gelf/issues/52) + ## [3.0.0] - 2020-03-15 ### Added - Allow encoder subclasses to customize the message before it is converted to String. diff --git a/src/main/java/de/siegmar/logbackgelf/GelfUdpChunker.java b/src/main/java/de/siegmar/logbackgelf/GelfUdpChunker.java index 59e43bf..7df4fb0 100644 --- a/src/main/java/de/siegmar/logbackgelf/GelfUdpChunker.java +++ b/src/main/java/de/siegmar/logbackgelf/GelfUdpChunker.java @@ -93,7 +93,7 @@ class GelfUdpChunker { this.maxChunkPayloadSize = mcs - HEADER_LENGTH; } - private static ByteBuffer buildChunk(final byte[] messageId, final byte[] message, + private static ByteBuffer buildChunk(final long messageId, final byte[] message, final byte chunkCount, final byte chunkNo, final int maxChunkPayloadSize) { @@ -106,7 +106,7 @@ private static ByteBuffer buildChunk(final byte[] messageId, final byte[] messag byteBuffer.put(CHUNKED_GELF_HEADER); // Message ID 8 bytes - byteBuffer.put(messageId); + byteBuffer.putLong(messageId); // Sequence number 1 byte byteBuffer.put(chunkNo); @@ -131,7 +131,7 @@ private final class ChunkIterator implements Iterator { private final byte[] message; private final int chunkSize; private final byte chunkCount; - private final byte[] messageId; + private final long messageId; private byte chunkIdx; @@ -156,7 +156,7 @@ private ChunkIterator(final byte[] message) { this.chunkSize = localChunkSize; this.chunkCount = (byte) localChunkCount; - messageId = localChunkCount > 1 ? messageIdSupplier.get() : null; + messageId = localChunkCount > 1 ? messageIdSupplier.get() : 0; } private int calcChunkCount(final byte[] msg, final int cs) { diff --git a/src/main/java/de/siegmar/logbackgelf/MessageIdSupplier.java b/src/main/java/de/siegmar/logbackgelf/MessageIdSupplier.java index a95a4b6..db513ff 100644 --- a/src/main/java/de/siegmar/logbackgelf/MessageIdSupplier.java +++ b/src/main/java/de/siegmar/logbackgelf/MessageIdSupplier.java @@ -19,55 +19,29 @@ package de.siegmar.logbackgelf; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import java.util.Random; +/** + * Supplier implementation for GELF message IDs as used for UDP chunks. Unfortunately the GELF + * protocol limits the message id length to 8 bytes thus an UUID cannot be used (16 bytes). + */ public class MessageIdSupplier { - protected static final int MESSAGE_ID_LENGTH = 8; - protected static final int LONG_LENGTH = 8; - private byte[] machinePart; - - public MessageIdSupplier() { - try { - machinePart = InetAddress.getLocalHost().getAddress(); - } catch (final UnknownHostException e) { - machinePart = new byte[LONG_LENGTH]; - new Random().nextBytes(machinePart); - } - } - - protected byte[] getMachinePart() { - return Arrays.copyOf(machinePart, machinePart.length); - } - - protected void setMachinePart(final byte[] machinePart) { - this.machinePart = Arrays.copyOf(machinePart, machinePart.length); - } + // static random to keep Spotbugs happy + private static final Random RANDOM = new Random(); + private int machinePart = RANDOM.nextInt(); - public byte[] get() { - return Arrays.copyOf(buildMessageId(), MESSAGE_ID_LENGTH); + public int getMachinePart() { + return machinePart; } - protected byte[] buildMessageId() { - final ByteBuffer bb = ByteBuffer.allocate(machinePart.length + LONG_LENGTH); - bb.put(machinePart); - bb.putLong(System.nanoTime()); - bb.flip(); - return md5(bb.array()); + public void setMachinePart(final int machinePart) { + this.machinePart = machinePart; } - protected static byte[] md5(final byte[] data) { - try { - return MessageDigest.getInstance("MD5").digest(data); - } catch (final NoSuchAlgorithmException e) { - throw new IllegalStateException(e); - } + @SuppressWarnings("checkstyle:magicnumber") + public Long get() { + return (long) machinePart << 32 | System.nanoTime() & 0xffffffffL; } } diff --git a/src/test/java/de/siegmar/logbackgelf/MessageIdSupplierTest.java b/src/test/java/de/siegmar/logbackgelf/MessageIdSupplierTest.java index 5c3af91..9561d37 100644 --- a/src/test/java/de/siegmar/logbackgelf/MessageIdSupplierTest.java +++ b/src/test/java/de/siegmar/logbackgelf/MessageIdSupplierTest.java @@ -19,23 +19,18 @@ package de.siegmar.logbackgelf; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import org.junit.jupiter.api.Test; public class MessageIdSupplierTest { - private static final int GELF_UDP_MESSAGE_ID_LENGTH = 8; - private MessageIdSupplier messageIdSupplier = new MessageIdSupplier(); + private final MessageIdSupplier messageIdSupplier = new MessageIdSupplier(); @Test public void test() { - final byte[] bytes = messageIdSupplier.get(); - assertEquals(GELF_UDP_MESSAGE_ID_LENGTH, bytes.length); - assertFalse(Arrays.equals(bytes, messageIdSupplier.get())); + final Long messageId = messageIdSupplier.get(); + assertNotEquals(messageId, messageIdSupplier.get()); } }