Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions src/main/java/ca/pjer/logback/AsyncWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import static ca.pjer.logback.AwsLogsAppender.MAX_BATCH_LOG_EVENTS;

import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
Expand All @@ -22,7 +20,7 @@ class AsyncWorker extends Worker implements Runnable {
private final int maxBatchLogEvents;
private final int discardThreshold;
private final AtomicBoolean running;
private final BlockingQueue<InputLogEvent> queue;
private final BlockingQueue<MemoizedEvent> queue;
private final AtomicLong lostCount;

private Thread thread;
Expand All @@ -32,7 +30,7 @@ class AsyncWorker extends Worker implements Runnable {
maxBatchLogEvents = awsLogsAppender.getMaxBatchLogEvents();
discardThreshold = (int) Math.ceil(maxBatchLogEvents * 1.5);
running = new AtomicBoolean(false);
queue = new ArrayBlockingQueue<InputLogEvent>(maxBatchLogEvents * 2);
queue = new ArrayBlockingQueue<>(maxBatchLogEvents * 2);
lostCount = new AtomicLong(0);
}

Expand Down Expand Up @@ -87,7 +85,7 @@ public void append(ILoggingEvent event) {
long now = System.currentTimeMillis();
while (now < until) {
try {
if (!queue.offer(logEvent, until - now, TimeUnit.MILLISECONDS)) {
if (!queue.offer(new MemoizedEvent(logEvent), until - now, TimeUnit.MILLISECONDS)) {
lostCount.incrementAndGet();
AwsLogsMetricsHolder.get().incrementLostCount();
}
Expand All @@ -104,7 +102,7 @@ public void append(ILoggingEvent event) {
}
} else {
// we are not allowed to block, offer without blocking
if (!queue.offer(logEvent)) {
if (!queue.offer(new MemoizedEvent(logEvent))) {
lostCount.incrementAndGet();
AwsLogsMetricsHolder.get().incrementLostCount();
}
Expand Down Expand Up @@ -160,12 +158,12 @@ private void flush(boolean all) {
private static final int MAX_BATCH_SIZE = 1048576;

private Collection<InputLogEvent> drainBatchFromQueue() {
Deque<InputLogEvent> batch = new ArrayDeque<InputLogEvent>(maxBatchLogEvents);
Deque<MemoizedEvent> batch = new ArrayDeque<>(maxBatchLogEvents);
queue.drainTo(batch, MAX_BATCH_LOG_EVENTS);
int batchSize = batchSize(batch);
while (batchSize > MAX_BATCH_SIZE) {
InputLogEvent removed = batch.removeLast();
batchSize -= eventSize(removed);
MemoizedEvent removed = batch.removeLast();
batchSize -= removed.eventSize();
if (!queue.offer(removed)) {
AwsLogsMetricsHolder.get().incrementBatchRequeueFailed();
if (getAwsLogsAppender().getVerbose()) {
Expand All @@ -175,13 +173,18 @@ private Collection<InputLogEvent> drainBatchFromQueue() {
}

AwsLogsMetricsHolder.get().incrementBatch(batchSize);
return batch;

List<InputLogEvent> array = new ArrayList<>(batchSize);
for (MemoizedEvent event : batch) {
array.add(event.event());
}
return array;
}

private static int batchSize(Collection<InputLogEvent> batch) {
private static int batchSize(Collection<MemoizedEvent> batch) {
int size = 0;
for (InputLogEvent event : batch) {
size += eventSize(event);
for (MemoizedEvent event : batch) {
size += event.eventSize();
}
return size;
}
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/ca/pjer/logback/MemoizedEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ca.pjer.logback;

import jdk.internal.RequiresIdentity;
import software.amazon.awssdk.services.cloudwatchlogs.model.InputLogEvent;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class MemoizedEvent {
// See http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
private static final int EVENT_SIZE_PADDING = 26;
private static final Charset EVENT_SIZE_CHARSET = StandardCharsets.UTF_8;

private final InputLogEvent event;
private byte[] messageBytes;

public MemoizedEvent(InputLogEvent event) {
this.event = event;
}

public InputLogEvent event() {
return event;
}

public byte[] getBytes() {
if (messageBytes == null) {
messageBytes = event.message().getBytes(EVENT_SIZE_CHARSET);
}
return messageBytes;
}

public int eventSize() {
return getBytes().length + EVENT_SIZE_PADDING;
}
}
4 changes: 2 additions & 2 deletions src/main/java/ca/pjer/logback/Worker.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ InputLogEvent asInputLogEvent(ILoggingEvent event) {
private static final int EVENT_SIZE_PADDING = 26;
private static final Charset EVENT_SIZE_CHARSET = Charset.forName("UTF-8");

static final int eventSize(InputLogEvent event) {
static int eventSize(InputLogEvent event) {
return eventSize(event.message());
}

static final int eventSize(String message) {
static int eventSize(String message) {
return message.getBytes(EVENT_SIZE_CHARSET).length + EVENT_SIZE_PADDING;
}

Expand Down