or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

hamcrest-matchers.mdindex.mdjunit-integration.mdmock-servers.mdtest-appenders.mdtest-categories.mdtesting-utilities.md

test-appenders.mddocs/

0

# Test Appenders

1

2

Test appenders for capturing and analyzing log events during testing. These specialized appenders provide essential functionality for verifying logging behavior, testing error scenarios, and validating threading behavior in Log4j applications.

3

4

## Capabilities

5

6

### ListAppender

7

8

The primary test appender for capturing log events in memory. Provides thread-safe collection of events, messages, and raw data with immutable snapshot access.

9

10

```java { .api }

11

/**

12

* Primary test appender that collects log events in lists for verification

13

* Plugin annotation: @Plugin(name = "List", category = Core.CATEGORY_NAME)

14

*/

15

@Plugin(name = "List", category = Core.CATEGORY_NAME)

16

public class ListAppender extends AbstractAppender {

17

18

/**

19

* Returns immutable snapshot of captured log events

20

* @return List of LogEvent objects

21

*/

22

public List<LogEvent> getEvents();

23

24

/**

25

* Returns immutable snapshot of formatted log messages

26

* @return List of formatted message strings

27

*/

28

public List<String> getMessages();

29

30

/**

31

* Returns immutable snapshot of raw serialized data

32

* @return List of byte arrays containing serialized data

33

*/

34

public List<byte[]> getData();

35

36

/**

37

* Clears all captured data and resets the appender

38

* @return This ListAppender instance for method chaining

39

*/

40

public ListAppender clear();

41

42

/**

43

* Retrieves a named ListAppender instance from the logger context

44

* @param name The name of the appender to retrieve

45

* @return The named ListAppender instance or null if not found

46

*/

47

public static ListAppender getListAppender(String name);

48

49

/**

50

* CountDownLatch for synchronizing asynchronous testing scenarios

51

* Volatile field for thread-safe access during concurrent testing

52

*/

53

public volatile CountDownLatch countDownLatch;

54

}

55

```

56

57

**Usage Examples:**

58

59

```java

60

import org.apache.logging.log4j.core.test.appender.ListAppender;

61

import org.apache.logging.log4j.core.test.junit.LoggerContextRule;

62

import org.junit.Rule;

63

import org.junit.Test;

64

65

public class ListAppenderTest {

66

67

@Rule

68

public LoggerContextRule context = new LoggerContextRule("log4j2-test.xml");

69

70

@Test

71

public void testEventCapture() {

72

ListAppender appender = context.getListAppender("TestList");

73

Logger logger = context.getLogger();

74

75

// Log some events

76

logger.info("Info message");

77

logger.warn("Warning message");

78

logger.error("Error message");

79

80

// Verify captured events

81

List<LogEvent> events = appender.getEvents();

82

assertEquals(3, events.size());

83

assertEquals(Level.INFO, events.get(0).getLevel());

84

assertEquals("Info message", events.get(0).getMessage().getFormattedMessage());

85

86

// Verify captured messages

87

List<String> messages = appender.getMessages();

88

assertEquals(3, messages.size());

89

assertTrue(messages.contains("Info message"));

90

91

// Clear for next test

92

appender.clear();

93

assertEquals(0, appender.getEvents().size());

94

}

95

96

@Test

97

public void testAsynchronousLogging() throws InterruptedException {

98

ListAppender appender = context.getListAppender("AsyncTestList");

99

appender.countDownLatch = new CountDownLatch(1);

100

101

Logger logger = context.getLogger();

102

logger.info("Async message");

103

104

// Wait for async processing

105

assertTrue(appender.countDownLatch.await(5, TimeUnit.SECONDS));

106

assertEquals(1, appender.getEvents().size());

107

}

108

}

109

```

110

111

### BlockingAppender

112

113

Appender that blocks on append operations for testing threading scenarios and deadlock detection.

114

115

```java { .api }

116

/**

117

* Appender that blocks for testing threading scenarios

118

* Plugin annotation: @Plugin(name = "Block", category = "Core")

119

*/

120

@Plugin(name = "Block", category = "Core")

121

public class BlockingAppender extends AbstractAppender {

122

123

/**

124

* Creates a blocking appender with the specified name

125

* @param name The name for the appender

126

* @return New BlockingAppender instance

127

*/

128

public static BlockingAppender createAppender(String name);

129

130

/**

131

* Indicates whether the appender is currently running/blocking

132

* Volatile field for thread-safe access

133

*/

134

public volatile boolean running;

135

}

136

```

137

138

### AlwaysFailAppender

139

140

Appender that always fails for testing error handling behavior.

141

142

```java { .api }

143

/**

144

* Appender that always fails for error handling testing

145

* Plugin annotation: @Plugin(name = "AlwaysFail", category = "Core")

146

*/

147

@Plugin(name = "AlwaysFail", category = "Core")

148

public class AlwaysFailAppender extends AbstractAppender {

149

150

/**

151

* Creates an appender that always fails on append operations

152

* @param name The name for the appender

153

* @return New AlwaysFailAppender instance

154

*/

155

public static AlwaysFailAppender createAppender(String name);

156

}

157

```

158

159

### FailOnceAppender

160

161

Appender that fails once then succeeds for testing resilience and recovery behavior.

162

163

```java { .api }

164

/**

165

* Appender that fails once then succeeds for resilience testing

166

* Plugin annotation: @Plugin(name = "FailOnce", category = "Core")

167

*/

168

@Plugin(name = "FailOnce", category = "Core")

169

public class FailOnceAppender extends AbstractAppender {

170

171

/**

172

* Creates an appender that fails on first append then succeeds

173

* @param name The name for the appender

174

* @return New FailOnceAppender instance

175

*/

176

public static FailOnceAppender createAppender(String name);

177

178

/**

179

* Enum defining types of exceptions to throw on failure

180

*/

181

public enum ThrowableClassName {

182

RUNTIME_EXCEPTION,

183

LOGGING_EXCEPTION,

184

IO_EXCEPTION

185

}

186

}

187

```

188

189

### InMemoryAppender

190

191

Memory-based appender for testing output stream functionality.

192

193

```java { .api }

194

/**

195

* Memory-based appender extending AbstractOutputStreamAppender

196

*/

197

public class InMemoryAppender extends AbstractOutputStreamAppender {

198

199

/**

200

* Creates an in-memory appender for testing stream operations

201

* @param name The name for the appender

202

* @param layout The layout to use for formatting

203

* @return New InMemoryAppender instance

204

*/

205

public static InMemoryAppender createAppender(String name, Layout<? extends Serializable> layout);

206

207

/**

208

* Gets the captured output as a string

209

* @return String representation of captured output

210

*/

211

public String getOutput();

212

213

/**

214

* OutputStreamManager implementation for memory-based operations

215

*/

216

public static class InMemoryManager extends OutputStreamManager {

217

public byte[] getBytes();

218

public String getString();

219

}

220

}

221

```

222

223

### EncodingListAppender

224

225

ListAppender with encoding support for testing character encoding scenarios.

226

227

```java { .api }

228

/**

229

* ListAppender with encoding support

230

* Extends ListAppender with character encoding capabilities

231

*/

232

public class EncodingListAppender extends ListAppender {

233

234

/**

235

* Creates an encoding-aware list appender

236

* @param name The name for the appender

237

* @param encoding The character encoding to use

238

* @return New EncodingListAppender instance

239

*/

240

public static EncodingListAppender createAppender(String name, String encoding);

241

242

/**

243

* Gets the character encoding used by this appender

244

* @return The character encoding name

245

*/

246

public String getEncoding();

247

}

248

```

249

250

## Usage Patterns

251

252

### Basic Event Verification

253

254

```java

255

// Configure ListAppender in log4j2-test.xml

256

ListAppender appender = context.getListAppender("TestAppender");

257

Logger logger = context.getLogger();

258

259

logger.info("Test message");

260

261

List<LogEvent> events = appender.getEvents();

262

assertEquals(1, events.size());

263

assertEquals(Level.INFO, events.get(0).getLevel());

264

```

265

266

### Error Handling Testing

267

268

```java

269

// Use AlwaysFailAppender to test error handling

270

AlwaysFailAppender failAppender = AlwaysFailAppender.createAppender("FailTest");

271

// Configure and test error scenarios

272

```

273

274

### Threading and Concurrency Testing

275

276

```java

277

// Use BlockingAppender for threading tests

278

BlockingAppender blockingAppender = BlockingAppender.createAppender("BlockTest");

279

// Test concurrent logging scenarios

280

```

281

282

### Resilience Testing

283

284

```java

285

// Use FailOnceAppender to test recovery

286

FailOnceAppender failOnceAppender = FailOnceAppender.createAppender("ResilienceTest");

287

// Test that logging recovers after initial failure

288

```