Skip to content
Open
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
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

.idea
*.iml


### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties

# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar


1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language: java
2 changes: 1 addition & 1 deletion java/logback-spike/LICENSE → LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 Patrick Kua
Copyright for portions of this project are held by Patrick Kua, 2016 as part of project thekua/Sample-Code. All other copyright for project schnatterer/logback-spike are held by Johannes Schnatterer, 2017.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# logback-spike
[![Build Status](https://travis-ci.org/schnatterer/logback-spike.svg?branch=master)](https://travis-ci.org/schnatterer/logback-spike)
[![JitPack](https://jitpack.io/v/schnatterer/logback-spike.svg)](https://jitpack.io/#schnatterer/logback-spike)
[![License](https://img.shields.io/github/license/schnatterer/logback-spike.svg)](LICENSE)

Logback and SLF4j unit testing.

Original idea from [thekua's blog](https://www.thekua.com/atwork/2011/11/testing-logging-with-logback/), forked from [his repo](https://github.com/thekua/Sample-Code/tree/master/java/logback-spike) in order to provide it conveniently with good reuse as maven dependency.

## Usage

Get it via [JitPack](https://jitpack.io/#schnatterer/logback-spike), for example using maven.

Add the following maven repository to your POM.xml

```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
```

Then add the actual dependency

```xml
<dependency>
<groupId>com.github.schnatterer</groupId>
<artifactId>logback-spike</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
```

From here it's really simple to use:
````java
// Given
LogbackCapturingAppender capturing = LogbackCapturingAppender.weaveInto(OurDomainWithLogger.LOG);

// when
new OurDomainWithLogger().logInfo("This should be logged{}", "!");

// then
assertThat(capturing.getCapturedLogMessages().get(0), is("This should be logged!"));
````
See [LogbackCapturingAppender's javadoc](src/main/java/com/thekua/spikes/LogbackCapturingAppender.java) and [its unit test](src/test/java/com/thekua/spikes/LogbackCapturingAppenderTest.java) for more insights.
5 changes: 0 additions & 5 deletions java/.gitignore

This file was deleted.

This file was deleted.

This file was deleted.

27 changes: 14 additions & 13 deletions java/logback-spike/pom.xml → pom.xml
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.thekua.spikes</groupId>
<artifactId>logback-spike</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>logback-spike</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<scm>
<connection>scm:git:git@github.com:schnatterer/logback-spike.git</connection>
<developerConnection>scm:git:git@github.com:schnatterer/logback-spike.git</developerConnection>
<url>https://github.com/schnatterer/logback-spike</url>
<tag>HEAD</tag>
</scm>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.0</version>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.8.2</version>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.2</version>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
100 changes: 100 additions & 0 deletions src/main/java/com/thekua/spikes/LogbackCapturingAppender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.thekua.spikes;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
* Logback appender that simply stores all logged messages of an {@link org.slf4j.Logger} in memory and provides methods
* to retrieve them, so they can be used in asserts of unit tests.
* <br/>
* Add a logger like so <br/>
* {@code LogbackCapturingAppender capturing = LogbackCapturingAppender.weaveInto(OurDomainWithLogger.LOG); }
* <br/><br/>
* Retrieve any log messages using any of the following methods:
* <ul>
* <li>{@link #getCapturedEvents()}</li>
* <li>{@link #getCapturedLogMessages()}</li>
* </ul>
* <br/>
* If necessary remove appender instance or all {@link LogbackCapturingAppender}s using
*
* <ul>
* <li>{@link #cleanUp()}</li>
* <li>{@link #cleanUpAll()}</li>
* </ul>
*/
public class LogbackCapturingAppender extends AppenderBase<ILoggingEvent> {
private static final List<LogbackCapturingAppender> ALL = new ArrayList<LogbackCapturingAppender>();

private final Logger logger;

private List<ILoggingEvent> capturedEvents = new LinkedList<ILoggingEvent>();

public static LogbackCapturingAppender weaveInto(org.slf4j.Logger sl4jLogger) {
LogbackCapturingAppender appender = new LogbackCapturingAppender(sl4jLogger);
ALL.add(appender);
return appender;
}

public static void cleanUpAll() {
for (LogbackCapturingAppender appender : ALL) {
appender.cleanUp();
}
}

public void cleanUp() {
logger.detachAppender(this);
}

/**
* @return whole event, including log level, unformatted message, etc.
*/
public List<ILoggingEvent> getCapturedEvents() {
return capturedEvents;
}

/**
* @return formatted message strings
*/
public List<String> getCapturedLogMessages() {
List<String> capturedMessages = new LinkedList<String>();
for (ILoggingEvent capturedEvent : capturedEvents) {
capturedMessages.add(capturedEvent.getFormattedMessage());
}
return capturedMessages;
}

@Override
protected void append(ILoggingEvent iLoggingEvent) {
capturedEvents.add(iLoggingEvent);
}

private LogbackCapturingAppender(org.slf4j.Logger sl4jLogger) {
this.logger = (Logger) sl4jLogger;
connect(logger);
detachDefaultConsoleAppender();
}

private void detachDefaultConsoleAppender() {
Logger rootLogger = getRootLogger();
Appender<ILoggingEvent> consoleAppender = rootLogger.getAppender("console");
rootLogger.detachAppender(consoleAppender);
}

private Logger getRootLogger() {
return logger.getLoggerContext().getLogger("ROOT");
}

private void connect(Logger logger) {
logger.setLevel(Level.ALL);
logger.addAppender(this);
this.start();
}
}
Loading