Skip to content

Commit

Permalink
MaskedKeyValuePairConverter test issues/828, NPE in AppeanderAttachab…
Browse files Browse the repository at this point in the history
…leImpl issues/822

Signed-off-by: Ceki Gulcu <ceki@qos.ch>
  • Loading branch information
ceki committed Aug 12, 2024
1 parent e7d9459 commit 44fbe63
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public final class Logger
/**
* It is assumed that once the 'aai' variable is set to a non-null value, it
* will never be reset to null. it is further assumed that only place where the
* 'aai'ariable is set is within the addAppender method. This method is
* 'aai variable is set is within the addAppender method. This method is
* synchronized on 'this' (Logger) protecting against simultaneous
* re-configuration of this logger (a very unlikely scenario).
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
* Assuming the specified key is k2, and the kvp list of an event contains {k1, v1}, {k2, v2}, the String output
* will be "k1=v1 k2=XXX", without the quotes.
*
* Value quotes can be specified as the first option, e.g %maskedKvp{SINGLE, k1}
*
* @author Ceki G&uuml;lc&uuml;
* @since 1.5.7
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<configuration>


<appender name="LIST" class="ch.qos.logback.core.testUtil.StringListAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%sample - %msg</Pattern>
</layout>
</appender>

<conversionRule conversionWord="sample"
converterClass="ch.qos.logback.classic.pattern.SampleConverter" />

<root level="debug">
<appender-ref ref="LIST" />
</root>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<included>


<appender name="LIST" class="ch.qos.logback.core.testUtil.StringListAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%sample - %msg</Pattern>
</layout>
</appender>

<conversionRule conversionWord="sample"
converterClass="ch.qos.logback.classic.pattern.SampleConverter" />

<root level="debug">
<appender-ref ref="LIST" />
</root>
</included>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<configuration>


<appender name="LIST" class="ch.qos.logback.core.testUtil.StringListAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%sample - %msg</Pattern>
</layout>
</appender>

<include file="src/test/input/joran/conversionRule/conversionRuleIncluded.xml"/>

<root level="debug">
<appender-ref ref="LIST" />
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,30 @@ public void testConversionRuleSupportInPatternLayout() throws JoranException {
assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
}

@Test
public void testConversionRuleAtEnd() throws JoranException {
configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "conversionRule/conversionRuleAtEnd.xml");
root.getAppender("LIST");
String msg = "testConversionRuleAtEnd";
logger.debug(msg);
StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
assertNotNull(sla);
assertEquals(1, sla.strList.size());
assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
}

@Test
public void testConversionRuleInIncluded() throws JoranException {
configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "conversionRule/conversionRuleTop0.xml");
root.getAppender("LIST");
String msg = "testConversionRuleInIncluded";
logger.debug(msg);
StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
assertNotNull(sla);
assertEquals(1, sla.strList.size());
assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
}

@Test
public void smokeReplace() {
pl.setPattern("%replace(a1234b){'\\d{4}', 'XXXX'}");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/

package ch.qos.logback.core.util;

import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.spi.AppenderAttachableImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;

import static org.assertj.core.api.Fail.fail;

@Disabled
public class COWArrayListConcurrencyTest {

//private static final int LIST_SIZE = 1_000_000;
private static final int LOOP_LEN = 1_0;
private static final int RECONFIGURE_DELAY = 1;

ReentrantLock reconfigureLock = new ReentrantLock(true);
ReentrantLock writeLock = new ReentrantLock(true);

private static int THREAD_COUNT = 200; //Runtime.getRuntime().availableProcessors()*200;
//private static int THREAD_COUNT = 5000;

private final ExecutorService tasksExecutor = Executors.newVirtualThreadPerTaskExecutor();
LoopingRunnable[] loopingThreads = new LoopingRunnable[THREAD_COUNT];
ReconfiguringThread[] reconfiguringThreads = new ReconfiguringThread[THREAD_COUNT];
Future<?>[] futures = new Future[THREAD_COUNT];

AppenderAttachableImpl<String> aai = new AppenderAttachableImpl<>();
Context context = new ContextBase();

void reconfigureWithDelay(AppenderAttachableImpl<String> aai) {
try {
reconfigureLock.lock();
aai.addAppender(makeNewNOPAppender());
aai.addAppender(makeNewNOPAppender());
delay(RECONFIGURE_DELAY);
aai.detachAndStopAllAppenders();
} finally {
reconfigureLock.unlock();
}
}

private Appender<String> makeNewNOPAppender() {
List<Long> longList = new ArrayList<>();
// for (int j = 0; j < LIST_SIZE; j++) {
// longList.add(0L);
// }
Appender<String> nopAppenderWithDelay = new NOPAppenderWithDelay<>(longList);
nopAppenderWithDelay.setContext(context);
nopAppenderWithDelay.start();
return nopAppenderWithDelay;
}

private void delay(int delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

@Test
void smoke() throws InterruptedException, ExecutionException {

for (int i = 0; i < THREAD_COUNT; i++) {
System.out.println("i="+i);
ReconfiguringThread rt = new ReconfiguringThread(aai);
futures[i] = tasksExecutor.submit(rt);
reconfiguringThreads[i] = rt;
}

for (int i = 0; i < THREAD_COUNT; i++) {
LoopingRunnable loopingThread = new LoopingRunnable(i, aai);
tasksExecutor.submit(loopingThread);
loopingThreads[i] = loopingThread;
}

for (int i = 0; i < THREAD_COUNT; i++) {
futures[i].get();
}

//reconfiguringThread.join();
Arrays.stream(loopingThreads).forEach(lt -> lt.active = false);

}

public class NOPAppenderWithDelay<E> extends AppenderBase<E> {

List<Long> longList;

NOPAppenderWithDelay(List<Long> longList) {
this.longList = new ArrayList<>(longList);
}

int i = 0;

@Override
protected void append(E eventObject) {
i++;
try {
writeLock.lock();
if ((i & 0xF) == 0) {
delay(1);
} else {
//longList.stream().map(x-> x+1);
}
} finally {
writeLock.unlock();
}

}

}

class ReconfiguringThread extends Thread {

AppenderAttachableImpl<String> aai;

ReconfiguringThread(AppenderAttachableImpl aai) {
this.aai = aai;
}

public void run() {
Thread.yield();
for (int i = 0; i < LOOP_LEN; i++) {
reconfigureWithDelay(aai);
}
}


}


class LoopingRunnable implements Runnable {

int num;
AppenderAttachableImpl<String> aai;
public boolean active = true;

LoopingRunnable(int num, AppenderAttachableImpl aai) {
this.num = num;
this.aai = aai;
}

public void run() {
System.out.println("LoopingRunnable.run.num="+num);
int i = 0;
while (active) {
if ((i & 0xFFFFF) == 0) {
long id = Thread.currentThread().threadId();
System.out.println("thread=" + id + " reconfigure=" + i);
}
aai.appendLoopOnAppenders(Integer.toString(i));
i++;
//Thread.yield();
}
}
}


}

0 comments on commit 44fbe63

Please sign in to comment.