or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

appender-factories.mdasync-logging.mdfilter-system.mdindex.mdlayout-system.mdlogging-factories.mdutility-classes.md

utility-classes.mddocs/

0

# Utility Classes

1

2

Essential utility classes for logging system management including bootstrap configuration, JDK logging integration, and resilient network streams. These classes provide the foundational infrastructure for Dropwizard's logging system.

3

4

## Capabilities

5

6

### BootstrapLogging

7

8

Configure logging before YAML configuration is read, essential for early application startup logging.

9

10

```java { .api }

11

/**

12

* Configure logging before YAML configuration is read

13

*/

14

public class BootstrapLogging {

15

/**

16

* Bootstrap logging with WARN level using default console appender

17

* Thread-safe and idempotent - safe to call multiple times

18

*/

19

public static void bootstrap();

20

21

/**

22

* Bootstrap logging with specified level using default console appender

23

* @param level the minimum logging level

24

*/

25

public static void bootstrap(Level level);

26

27

/**

28

* Bootstrap logging with specified level and custom layout

29

* @param level the minimum logging level

30

* @param layoutFactory factory for creating custom layout

31

*/

32

public static void bootstrap(Level level, DiscoverableLayoutFactory<ILoggingEvent> layoutFactory);

33

}

34

```

35

36

**Usage Examples:**

37

38

```java

39

// Basic bootstrap with WARN level

40

BootstrapLogging.bootstrap();

41

42

// Bootstrap with INFO level for more verbose startup logging

43

BootstrapLogging.bootstrap(Level.INFO);

44

45

// Bootstrap with custom layout

46

DropwizardLayoutFactory customLayout = new DropwizardLayoutFactory();

47

BootstrapLogging.bootstrap(Level.DEBUG, customLayout);

48

49

// Safe to call multiple times - subsequent calls are ignored

50

BootstrapLogging.bootstrap();

51

BootstrapLogging.bootstrap(Level.ERROR); // This call has no effect

52

```

53

54

**Thread Safety:**

55

- Uses `ReentrantLock` for thread-safe initialization

56

- Idempotent - safe to call from multiple threads

57

- First call wins - subsequent calls are ignored

58

59

### LoggingUtil

60

61

Logging utility methods for system integration and logger context management.

62

63

```java { .api }

64

/**

65

* Logging utility methods

66

*/

67

public class LoggingUtil {

68

/**

69

* Safely acquire LoggerContext with retry logic

70

* Handles cases where LoggerContext is not immediately available

71

* @return the Logback LoggerContext

72

* @throws IllegalStateException if context cannot be acquired

73

*/

74

public static LoggerContext getLoggerContext();

75

76

/**

77

* Redirect JUL (Java Util Logging) to SLF4J

78

* Thread-safe and idempotent - safe to call multiple times

79

* Installs SLF4JBridgeHandler to capture JUL events

80

*/

81

public static void hijackJDKLogging();

82

}

83

```

84

85

**Usage Examples:**

86

87

```java

88

// Get logger context for configuration

89

LoggerContext context = LoggingUtil.getLoggerContext();

90

91

// Configure appenders programmatically

92

Logger rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME);

93

ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();

94

appender.setContext(context);

95

appender.start();

96

rootLogger.addAppender(appender);

97

98

// Redirect JDK logging to SLF4J (commonly done at application startup)

99

LoggingUtil.hijackJDKLogging();

100

101

// Now JUL loggers will route through SLF4J/Logback

102

java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("com.example.MyClass");

103

julLogger.info("This will appear in Logback appenders");

104

```

105

106

### ResilientOutputStreamBase

107

108

Abstract base class for resilient output streams that automatically recover from connection failures.

109

110

```java { .api }

111

/**

112

* Base class for resilient output streams with recovery logic

113

*/

114

public abstract class ResilientOutputStreamBase extends OutputStream {

115

/**

116

* Get description of this stream for logging purposes

117

* @return human-readable description

118

*/

119

protected abstract String getDescription();

120

121

/**

122

* Open a new output stream (called on initial connection and reconnection)

123

* @return new OutputStream instance

124

* @throws IOException if stream cannot be opened

125

*/

126

protected abstract OutputStream openNewOutputStream() throws IOException;

127

128

/**

129

* Write a single byte with automatic recovery

130

* @param b the byte to write

131

* @throws IOException if write fails after retry attempts

132

*/

133

@Override

134

public void write(int b) throws IOException;

135

136

/**

137

* Write byte array with automatic recovery

138

* @param b the byte array

139

* @param off the offset

140

* @param len the length

141

* @throws IOException if write fails after retry attempts

142

*/

143

@Override

144

public void write(byte[] b, int off, int len) throws IOException;

145

146

/**

147

* Flush the output stream

148

* @throws IOException if flush fails

149

*/

150

@Override

151

public void flush() throws IOException;

152

153

/**

154

* Close the output stream

155

* @throws IOException if close fails

156

*/

157

@Override

158

public void close() throws IOException;

159

}

160

```

161

162

### ResilientSocketOutputStream

163

164

Resilient TCP connection implementation that automatically reconnects on connection failures.

165

166

```java { .api }

167

/**

168

* Resilient TCP connection as OutputStream with automatic reconnection

169

*/

170

public class ResilientSocketOutputStream extends ResilientOutputStreamBase {

171

/**

172

* Create resilient socket output stream

173

* @param host target hostname or IP address

174

* @param port target port number

175

* @param connectionTimeoutMs connection timeout in milliseconds

176

* @param sendBufferSize TCP send buffer size in bytes

177

* @param socketFactory factory for creating socket connections

178

*/

179

public ResilientSocketOutputStream(String host, int port, int connectionTimeoutMs,

180

int sendBufferSize, SocketFactory socketFactory);

181

182

/**

183

* Get description of this socket connection

184

* @return description in format "host:port"

185

*/

186

@Override

187

protected String getDescription();

188

189

/**

190

* Open new socket connection with configured parameters

191

* @return OutputStream from the socket connection

192

* @throws IOException if connection cannot be established

193

*/

194

@Override

195

protected OutputStream openNewOutputStream() throws IOException;

196

}

197

```

198

199

**Usage Example:**

200

201

```java

202

// Create resilient socket connection for log forwarding

203

String host = "log-server.example.com";

204

int port = 514;

205

int connectionTimeout = 5000; // 5 seconds

206

int sendBufferSize = 8192; // 8KB buffer

207

SocketFactory socketFactory = SocketFactory.getDefault();

208

209

ResilientSocketOutputStream socketStream = new ResilientSocketOutputStream(

210

host, port, connectionTimeout, sendBufferSize, socketFactory);

211

212

// Use with any appender that accepts OutputStream

213

OutputStreamAppender<ILoggingEvent> appender = new OutputStreamAppender<>();

214

appender.setOutputStream(socketStream);

215

appender.setEncoder(new PatternLayoutEncoder());

216

appender.start();

217

218

// Stream will automatically reconnect on network failures

219

try {

220

socketStream.write("Log message\n".getBytes());

221

socketStream.flush();

222

} catch (IOException e) {

223

// Connection failed and could not be reestablished

224

logger.error("Failed to write to remote log server", e);

225

}

226

```

227

228

### Socket Appender Implementations

229

230

Ready-to-use socket appenders built on the resilient stream infrastructure.

231

232

#### DropwizardSocketAppender

233

234

TCP socket appender with resilient connection handling.

235

236

```java { .api }

237

/**

238

* TCP socket appender with resilient connection handling

239

*/

240

public class DropwizardSocketAppender<E> extends OutputStreamAppender<E> {

241

/**

242

* Create TCP socket appender

243

* @param host target hostname

244

* @param port target port

245

* @param connectionTimeoutMs connection timeout

246

* @param sendBufferSize send buffer size

247

* @param socketFactory socket factory for connections

248

*/

249

public DropwizardSocketAppender(String host, int port, int connectionTimeoutMs,

250

int sendBufferSize, SocketFactory socketFactory);

251

}

252

```

253

254

#### DropwizardUdpSocketAppender

255

256

UDP socket appender for datagram-based log forwarding.

257

258

```java { .api }

259

/**

260

* UDP socket appender with datagram support

261

*/

262

public class DropwizardUdpSocketAppender<E> extends OutputStreamAppender<E> {

263

/**

264

* Create UDP socket appender

265

* @param host target hostname

266

* @param port target port

267

*/

268

public DropwizardUdpSocketAppender(String host, int port);

269

}

270

```

271

272

**Usage Examples:**

273

274

```java

275

// TCP socket appender

276

DropwizardSocketAppender<ILoggingEvent> tcpAppender = new DropwizardSocketAppender<>(

277

"log-server.example.com", 514, 5000, 8192, SocketFactory.getDefault());

278

tcpAppender.setContext(context);

279

tcpAppender.setEncoder(encoder);

280

tcpAppender.start();

281

282

// UDP socket appender

283

DropwizardUdpSocketAppender<ILoggingEvent> udpAppender = new DropwizardUdpSocketAppender<>(

284

"syslog-server.example.com", 514);

285

udpAppender.setContext(context);

286

udpAppender.setEncoder(encoder);

287

udpAppender.start();

288

```

289

290

## Integration Examples

291

292

### Complete Bootstrap and Configuration

293

294

```java

295

public class ApplicationMain {

296

public static void main(String[] args) {

297

// 1. Bootstrap logging early

298

BootstrapLogging.bootstrap(Level.INFO);

299

300

// 2. Redirect JDK logging

301

LoggingUtil.hijackJDKLogging();

302

303

// 3. Log early startup messages

304

Logger logger = LoggerFactory.getLogger(ApplicationMain.class);

305

logger.info("Application starting...");

306

307

try {

308

// 4. Load and configure full logging system

309

DefaultLoggingFactory loggingFactory = loadLoggingConfiguration();

310

MetricRegistry metrics = new MetricRegistry();

311

loggingFactory.configure(metrics, "MyApplication");

312

313

logger.info("Logging system configured");

314

315

// 5. Start application

316

startApplication();

317

318

} catch (Exception e) {

319

logger.error("Application startup failed", e);

320

System.exit(1);

321

}

322

}

323

324

private static DefaultLoggingFactory loadLoggingConfiguration() {

325

// Load from YAML, environment, etc.

326

DefaultLoggingFactory factory = new DefaultLoggingFactory();

327

factory.setLevel("INFO");

328

329

// Add file appender with resilient network backup

330

FileAppenderFactory<ILoggingEvent> fileAppender = new FileAppenderFactory<>();

331

fileAppender.setCurrentLogFilename("./logs/application.log");

332

333

TcpSocketAppenderFactory<ILoggingEvent> networkAppender = new TcpSocketAppenderFactory<>();

334

networkAppender.setHost("log-aggregator.example.com");

335

networkAppender.setPort(514);

336

337

factory.setAppenders(Arrays.asList(fileAppender, networkAppender));

338

return factory;

339

}

340

}

341

```

342

343

### Custom Resilient Stream

344

345

```java

346

/**

347

* Custom resilient stream for database logging

348

*/

349

public class ResilientDatabaseOutputStream extends ResilientOutputStreamBase {

350

private final String jdbcUrl;

351

private final String username;

352

private final String password;

353

354

public ResilientDatabaseOutputStream(String jdbcUrl, String username, String password) {

355

this.jdbcUrl = jdbcUrl;

356

this.username = username;

357

this.password = password;

358

}

359

360

@Override

361

protected String getDescription() {

362

return "Database: " + jdbcUrl;

363

}

364

365

@Override

366

protected OutputStream openNewOutputStream() throws IOException {

367

try {

368

Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

369

return new DatabaseOutputStream(connection);

370

} catch (SQLException e) {

371

throw new IOException("Failed to connect to database", e);

372

}

373

}

374

}

375

376

// Usage with custom appender

377

ResilientDatabaseOutputStream dbStream = new ResilientDatabaseOutputStream(

378

"jdbc:postgresql://db.example.com/logs", "loguser", "logpass");

379

380

OutputStreamAppender<ILoggingEvent> dbAppender = new OutputStreamAppender<>();

381

dbAppender.setOutputStream(dbStream);

382

dbAppender.setEncoder(new JsonEncoder());

383

dbAppender.start();

384

```