Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: qos-ch/logback
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 99a372643a53541494038d0c70100ab08c0d31e8
Choose a base ref
..
head repository: qos-ch/logback
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 356a4e92d3ba50a4b625b76a20cece306f8fb3ab
Choose a head ref
19 changes: 17 additions & 2 deletions logback-classic/src/main/java/ch/qos/logback/classic/Level.java
Original file line number Diff line number Diff line change
@@ -45,7 +45,11 @@ public final class Level implements java.io.Serializable {
public static final Integer ALL_INTEGER = ALL_INT;

/**
* The <code>OFF</code> is used to turn off logging.
* The <code>OFF</code> is used to turn off logging. It is intended to be used
* for logging system configuration.
*
* Warning: it should never be passed as an argument to logger methods
* in a regular log statement.
*/
public static final Level OFF = new Level(OFF_INT, "OFF");

@@ -79,7 +83,18 @@ public final class Level implements java.io.Serializable {
public static final Level TRACE = new Level(TRACE_INT, "TRACE");

/**
* The <code>ALL</code> is used to turn on all logging.
* <p>The <code>ALL</code> is used to turn on all logging. The <code>ALL</code> level is vestigial from
* log4j 1.x.
* </p>
*
* <p>In logback, where the Level class is final, logging can be turned on for all levels by setting
* a logger's level to <code>TRACE</code>.
* </p>
*
* <p>Thus, the <code>ALL</code> level is marked as deprecated.
* </p>
*
* @deprecated with no replacement
*/
public static final Level ALL = new Level(ALL_INT, "ALL");

Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

import ch.qos.logback.core.helpers.CyclicBuffer;
import ch.qos.logback.core.spi.LogbackLock;
@@ -29,7 +30,7 @@ public class BasicStatusManager implements StatusManager {
public static final int MAX_HEADER_COUNT = 150;
public static final int TAIL_SIZE = 150;

final AtomicInteger count = new AtomicInteger(0);
final LongAdder count = new LongAdder();

// protected access was requested in http://jira.qos.ch/browse/LBCORE-36
final protected List<Status> statusList = new ArrayList<Status>();
@@ -58,9 +59,9 @@ public void add(Status newStatus) {
// LBCORE-72: fire event before the count check
fireStatusAddEvent(newStatus);

count.getAndIncrement();
int currentLevel;
count.increment();
int newLevel = newStatus.getLevel();
int currentLevel;
do {
currentLevel = level.get();
if (newLevel <= currentLevel) {
@@ -96,7 +97,7 @@ private void fireStatusAddEvent(Status status) {

public void clear() {
synchronized (statusListLock) {
count.set(0);
count.reset();
statusList.clear();
tailBuffer.clear();
}
@@ -107,7 +108,7 @@ public int getLevel() {
}

public int getCount() {
return count.get();
return count.intValue();
}

/**
Original file line number Diff line number Diff line change
@@ -136,7 +136,7 @@ public void stop() {
protected void closeOutputStream() {
if (this.outputStream != null) {
try {
// before closing we have to output out layout's footer
// before closing we have to output out encooder's footer
encoderClose();
this.outputStream.close();
this.outputStream = null;
@@ -174,6 +174,8 @@ public void setOutputStream(OutputStream outputStream) {
closeOutputStream();
this.outputStream = outputStream;

// after opening we have to output the header
encoderInit();
} finally {
streamWriteLock.unlock();
}
@@ -204,6 +206,8 @@ private void writeBytes(byte[] byteArray) throws IOException {
streamWriteLock.lock();

try {
// guard against appender having been stop() in parallel
// note that the encoding step is performed outside the protection of the streamWriteLock
if(isStarted()) {
writeByteArrayToOutputStreamWithPossibleFlush(byteArray);
updateByteCount(byteArray);
Original file line number Diff line number Diff line change
@@ -24,15 +24,15 @@ public class JsonEscapeUtil {

// From RFC-8259 page 5

// %x22 / ; " quotation mark U+0022
// %x5C / ; \ reverse solidus U+005C
// %x2F / ; / solidus U+002F
// " quotation mark U+0022 -- escaped as \"
// \ reverse solidus U+005C -- escaped as \\
// / solidus U+002F -- escaped as \/

// %x62 / ; b backspace U+0008
// %x74 / ; t tab U+0009
// %x6E / ; n line feed U+000A
// %x66 / ; f form feed U+000C
// %x72 / ; r carriage return U+000D
// backspace U+0008 -- escaped as \b
// tab U+0009 -- escaped as \t
// line feed U+000A -- escaped as \n
// form feed U+000C -- escaped as \f
// carriage return U+000D -- escaped as \r

static {
for (char c = 0; c < ESCAPE_CODES_COUNT; c++) {
@@ -77,16 +77,19 @@ private static String _computeEscapeCodeBelowASCII32(char c) {
return sb.toString();
}

// %x22 / ; " quotation mark U+0022
// %x5C / ; \ reverse solidus U+005C
// " quotation mark U+0022 -- escaped as \"
// \ reverse solidus U+005C -- escaped as \\
// / solidus U+002F -- escaped as \/

static String getObligatoryEscapeCode(char c) {
if (c < 32)
return ESCAPE_CODES[c];
if (c == 0x22)
return "\\\"";
if (c == 0x5C)
if (c == 0x2F)
return "\\/";
if (c == 0x5C)
return "\\\\";

return null;
}
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
class JsonEscapeUtilTest {

@Test
public void smokeTestEscapeCodes() {
public void smokeTestEscapeCodesUnder32() {
assertEquals("\\u0001", JsonEscapeUtil.ESCAPE_CODES[1]);
assertEquals("\\u0005", JsonEscapeUtil.ESCAPE_CODES[5]);
assertEquals("\\b", JsonEscapeUtil.ESCAPE_CODES[8]);
@@ -49,6 +49,22 @@ public void testEscapingLF() {
assertEquals("{\\nhello: "+'\\'+'"'+"wo\\nrld\\\"}", JsonEscapeUtil.jsonEscapeString(input));
}

@Test
public void testBackslash() {
String input = "{x:com\\foo}";
System.out.println(input);
assertEquals("{x:com\\\\foo}", JsonEscapeUtil.jsonEscapeString(input));
}

@Test
public void testForwardslash() {
String input = "{x:com/foo}";
System.out.println(input);
assertEquals("{x:com\\/foo}", JsonEscapeUtil.jsonEscapeString(input));
}



@Test
public void testEscapingTab() {
String input = "{hello: \"\tworld\"}";
Original file line number Diff line number Diff line change
@@ -13,9 +13,12 @@
*/
package ch.qos.logback.core.rolling;

import ch.qos.logback.core.util.Duration;
import ch.qos.logback.core.util.FileSize;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import ch.qos.logback.core.Appender;
@@ -27,6 +30,14 @@
import ch.qos.logback.core.testUtil.CoreTestConstants;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.status.testUtil.StatusChecker;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;
//import ch.qos.logback.core.util.StatusPrinter;

public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
@@ -37,13 +48,14 @@ public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
int diff = RandomUtil.getPositiveInt();
String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
DummyEncoder<Object> encoder;

@BeforeEach
public void setUp() throws Exception {
// noStartTest fails if the context is set in setUp
// rfa.setContext(context);

rfa.setEncoder(new DummyEncoder<Object>());
encoder = new DummyEncoder<>();
rfa.setEncoder(encoder);
rfa.setName("test");
tbrp.setContext(context);
tbrp.setParent(rfa);
@@ -260,4 +272,54 @@ public void collidingFileNamePattern() {
checker.assertContainsMatch(Status.ERROR, "'FileNamePattern' option has the same value");
}

@Test
@DisplayName("Checks header and footer are written when the files are rolled")
public void testHeaderFooterWritten() throws IOException, InterruptedException {
for (int i = 0; i < 8; i++) {
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + i + ".log");
file.deleteOnExit();
}
encoder.setFileHeader("HEADER");
encoder.setFileFooter("FOOTER");
rfa.setContext(context);
FixedWindowRollingPolicy fixedWindowRollingPolicy = new FixedWindowRollingPolicy();
fixedWindowRollingPolicy.setContext(context);
fixedWindowRollingPolicy.setParent(rfa);
fixedWindowRollingPolicy.setMaxIndex(3);
String fileNamePattern = CoreTestConstants.OUTPUT_DIR_PREFIX + "header-%i.log";
fixedWindowRollingPolicy.setFileNamePattern(fileNamePattern);
rfa.setRollingPolicy(fixedWindowRollingPolicy);
rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-0.log");
fixedWindowRollingPolicy.start();
rfa.setImmediateFlush(true);
SizeBasedTriggeringPolicy<Object> sbtp = new SizeBasedTriggeringPolicy<>();
sbtp.setMaxFileSize(new FileSize(10));
sbtp.setCheckIncrement(Duration.buildByMilliseconds(10));

rfa.setTriggeringPolicy(sbtp);
rfa.getTriggeringPolicy().start();
rfa.start();

for (int i = 0; i < 100; i++) {
rfa.doAppend("data" + i);
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + fixedWindowRollingPolicy.getMaxIndex() + ".log");
if (file.exists()) {
break;
}
Thread.sleep(5);
}
rfa.stop();

for (int i = 0; i < fixedWindowRollingPolicy.getMaxIndex(); i++) {
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + i + ".log");
Assertions.assertTrue(file.exists());
List<String> lines = Files.readAllLines(file.toPath());
Assertions.assertTrue(lines.size() > 2, "At least 2 lines per file are expected in " + file);
Assertions.assertEquals("HEADER", lines.get(0));
Assertions.assertEquals("FOOTER", lines.get(lines.size() - 1));
Assertions.assertEquals(1, Collections.frequency(lines, "HEADER"));
Assertions.assertEquals(1, Collections.frequency(lines, "FOOTER"));
}
}

}