or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdconfiguration.mdcontext.mdconversion.mdindex.mdjson.mdlogging.mdweb.md

logging.mddocs/

0

# Logging Configuration

1

2

Spring Boot's logging system provides abstraction over multiple logging frameworks with automatic configuration, log level management, and flexible output formatting. It supports Logback, Log4j2, and Java Util Logging with sensible defaults.

3

4

## Capabilities

5

6

### Logging System Abstraction

7

8

Core abstraction for logging system configuration and management.

9

10

```java { .api }

11

/**

12

* Common abstraction over logging systems

13

*/

14

public abstract class LoggingSystem {

15

16

/**

17

* The property used to configure the logging system

18

*/

19

public static final String SYSTEM_PROPERTY = LoggingSystem.class.getName();

20

21

/**

22

* The value that disables the logging system

23

*/

24

public static final String NONE = "none";

25

26

/**

27

* Get the logging system for the given class loader

28

* @param classLoader the class loader

29

* @return the logging system or null if not available

30

*/

31

public static LoggingSystem get(ClassLoader classLoader) {

32

String loggingSystemClassName = System.getProperty(SYSTEM_PROPERTY);

33

if (StringUtils.hasLength(loggingSystemClassName)) {

34

if (NONE.equals(loggingSystemClassName)) {

35

return new NoOpLoggingSystem();

36

}

37

return get(classLoader, loggingSystemClassName);

38

}

39

return LOGGING_SYSTEM_FACTORY.getLoggingSystem(classLoader);

40

}

41

42

/**

43

* Detect if a logging system is present on the classpath

44

* @param classLoader the class loader to check

45

* @return true if available

46

*/

47

public static boolean get(ClassLoader classLoader) {

48

try {

49

return get(classLoader) != null;

50

} catch (Exception ex) {

51

return false;

52

}

53

}

54

55

/**

56

* Initialize the logging system

57

* @param initializationContext the initialization context

58

* @param configLocation the config location or null if default should be used

59

* @param logFile the log file that should be written or null for console output

60

*/

61

public abstract void initialize(LoggingInitializationContext initializationContext,

62

String configLocation, LogFile logFile);

63

64

/**

65

* Clean up the logging system. The default implementation does nothing.

66

*/

67

public void cleanUp() {

68

}

69

70

/**

71

* Returns a Runnable that can handle shutdown of this logging system when the JVM

72

* exits. The default implementation returns null, indicating that no shutdown

73

* is required

74

* @return the shutdown handler, or null

75

*/

76

public Runnable getShutdownHandler() {

77

return null;

78

}

79

80

/**

81

* Set the log level for the given logger name

82

* @param loggerName the name of the logger to set (null indicates the root logger)

83

* @param level the log level (null removes any custom level for the logger and

84

* uses the default configuration instead)

85

*/

86

public abstract void setLogLevel(String loggerName, LogLevel level);

87

88

/**

89

* Return the supported log levels

90

* @return the supported levels

91

*/

92

public abstract List<LogLevel> getSupportedLogLevels();

93

}

94

95

/**

96

* Logging initialization context used by LoggingSystem implementations

97

*/

98

public interface LoggingInitializationContext {

99

100

/**

101

* Return the Spring Environment (may be null)

102

* @return the environment

103

*/

104

Environment getEnvironment();

105

}

106

107

/**

108

* A reference to a log output file

109

*/

110

public class LogFile {

111

112

/**

113

* The name of the Spring property that contains the name of the log file. Names can

114

* be an exact location or relative to the current directory

115

*/

116

public static final String FILE_PROPERTY = "logging.file.name";

117

118

/**

119

* The name of the Spring property that contains the directory where log files are

120

* written

121

*/

122

public static final String PATH_PROPERTY = "logging.file.path";

123

124

/**

125

* Get a LogFile from the given Spring Environment

126

* @param environment the Spring environment

127

* @return a LogFile instance or null if the environment contains no log file

128

* properties

129

*/

130

public static LogFile get(Environment environment);

131

132

/**

133

* Return the name of the log file

134

* @return the log file name

135

*/

136

public String getName();

137

138

/**

139

* Return a string representation of the log file

140

* @return the log file as a string

141

*/

142

@Override

143

public String toString();

144

}

145

```

146

147

**Usage Examples:**

148

149

```java

150

@Component

151

public class LoggingManager {

152

153

private final LoggingSystem loggingSystem;

154

155

public LoggingManager() {

156

this.loggingSystem = LoggingSystem.get(getClass().getClassLoader());

157

}

158

159

public void setLogLevel(String loggerName, LogLevel level) {

160

if (loggingSystem != null) {

161

loggingSystem.setLogLevel(loggerName, level);

162

System.out.println("Set log level for " + loggerName + " to " + level);

163

}

164

}

165

166

public List<LogLevel> getSupportedLevels() {

167

return loggingSystem != null ?

168

loggingSystem.getSupportedLogLevels() :

169

Collections.emptyList();

170

}

171

172

@EventListener

173

public void onApplicationReady(ApplicationReadyEvent event) {

174

// Set debug level for specific packages during development

175

setLogLevel("com.example.service", LogLevel.DEBUG);

176

setLogLevel("org.springframework.security", LogLevel.TRACE);

177

178

System.out.println("Supported log levels: " + getSupportedLevels());

179

}

180

}

181

```

182

183

### Log Levels

184

185

Enumeration of log levels supported by Spring Boot.

186

187

```java { .api }

188

/**

189

* Logging levels supported by a LoggingSystem

190

*/

191

public enum LogLevel {

192

193

TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF;

194

195

/**

196

* Return the name of this log level in lower case

197

* @return the lower case name

198

*/

199

public String name() {

200

return super.name().toLowerCase();

201

}

202

203

/**

204

* Return the name of this log level in upper case

205

* @return the upper case name

206

*/

207

public String toString() {

208

return super.toString();

209

}

210

211

/**

212

* Return a LogLevel for the given String representation

213

* @param name the log level name

214

* @return the LogLevel or null if not found

215

*/

216

public static LogLevel valueOf(String name) {

217

if (name == null) {

218

return null;

219

}

220

try {

221

return LogLevel.valueOf(name.trim().toUpperCase());

222

} catch (IllegalArgumentException ex) {

223

return null;

224

}

225

}

226

}

227

```

228

229

**Usage Examples:**

230

231

```java

232

@RestController

233

@RequestMapping("/admin/logging")

234

public class LoggingController {

235

236

@Autowired

237

private LoggingSystem loggingSystem;

238

239

@PostMapping("/level")

240

public ResponseEntity<?> setLogLevel(@RequestParam String logger,

241

@RequestParam String level) {

242

try {

243

LogLevel logLevel = LogLevel.valueOf(level.toUpperCase());

244

if (logLevel == null) {

245

return ResponseEntity.badRequest()

246

.body("Invalid log level. Supported levels: " +

247

loggingSystem.getSupportedLogLevels());

248

}

249

250

loggingSystem.setLogLevel(logger, logLevel);

251

return ResponseEntity.ok()

252

.body(String.format("Set log level for '%s' to %s", logger, logLevel));

253

254

} catch (IllegalArgumentException e) {

255

return ResponseEntity.badRequest()

256

.body("Invalid log level: " + level);

257

}

258

}

259

260

@GetMapping("/levels")

261

public List<LogLevel> getSupportedLevels() {

262

return loggingSystem.getSupportedLogLevels();

263

}

264

265

@PostMapping("/reset")

266

public ResponseEntity<?> resetLogLevel(@RequestParam String logger) {

267

loggingSystem.setLogLevel(logger, null); // Reset to default

268

return ResponseEntity.ok()

269

.body("Reset log level for '" + logger + "' to default");

270

}

271

}

272

```

273

274

### Logging Configuration Properties

275

276

Spring Boot properties for configuring logging behavior.

277

278

```java { .api }

279

/**

280

* Configuration properties for logging

281

*/

282

@ConfigurationProperties(prefix = "logging")

283

public class LoggingProperties {

284

285

/**

286

* Logging pattern for the console. Supported only with the default Logback setup

287

*/

288

private String pattern;

289

290

/**

291

* Logging pattern for file output. Supported only with the default Logback setup

292

*/

293

private String filePattern;

294

295

/**

296

* Log level severity mapping. For instance, `logging.level.org.springframework=DEBUG`

297

*/

298

private Map<String, LogLevel> level = new LinkedHashMap<>();

299

300

/**

301

* Location of the logging configuration file. For instance, `classpath:logback-spring.xml` for Logback

302

*/

303

private String config;

304

305

/**

306

* Whether to enable debug logging of auto-configuration conditions

307

*/

308

private boolean enableAutoConfigurationReport = false;

309

310

private final File file = new File();

311

private final Logback logback = new Logback();

312

private final Log4j2 log4j2 = new Log4j2();

313

314

public static class File {

315

316

/**

317

* Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory

318

*/

319

private String name;

320

321

/**

322

* Location of the log file. For instance, `/var/log`

323

*/

324

private String path;

325

326

/**

327

* Maximum log file size. Only supported with the default logback setup

328

*/

329

private DataSize maxSize = DataSize.ofMegabytes(10);

330

331

/**

332

* Maximum number of archive log files to keep. Only supported with the default logback setup

333

*/

334

private int maxHistory = 7;

335

336

/**

337

* Total size of log backups to be kept. Only supported with the default logback setup

338

*/

339

private DataSize totalSizeCap = DataSize.ofGigabytes(0);

340

341

// Getters and setters

342

}

343

344

public static class Logback {

345

346

/**

347

* Rollover policy to use when log files exceed the maximum size

348

*/

349

private RollingPolicy rollingPolicy = new RollingPolicy();

350

351

public static class RollingPolicy {

352

353

/**

354

* Filename pattern used to create log archives

355

*/

356

private String fileNamePattern = "${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz";

357

358

/**

359

* Whether to clean history on start up

360

*/

361

private boolean cleanHistoryOnStart = false;

362

363

/**

364

* Maximum number of archive files to keep

365

*/

366

private int maxFileSize = 7;

367

368

/**

369

* Maximum size of the log file before it gets archived

370

*/

371

private DataSize maxFileSize = DataSize.ofMegabytes(10);

372

373

/**

374

* Total size of all log files

375

*/

376

private DataSize totalSizeCap = DataSize.ofGigabytes(0);

377

}

378

}

379

}

380

```

381

382

**Usage Examples:**

383

384

```java

385

# Application properties for logging configuration

386

logging.level.org.springframework.security=DEBUG

387

logging.level.org.hibernate.SQL=DEBUG

388

logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

389

logging.level.com.example=INFO

390

391

# File logging

392

logging.file.name=application.log

393

logging.file.path=/var/log/myapp

394

logging.file.max-size=50MB

395

logging.file.max-history=30

396

logging.file.total-size-cap=1GB

397

398

# Pattern configuration

399

logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n

400

logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

401

402

# Custom logback configuration

403

logging.config=classpath:logback-spring.xml

404

405

# Enable auto-configuration report

406

logging.level.org.springframework.boot.autoconfigure=DEBUG

407

408

@Configuration

409

@EnableConfigurationProperties(LoggingProperties.class)

410

public class CustomLoggingConfiguration {

411

412

@Autowired

413

private LoggingProperties loggingProperties;

414

415

@Bean

416

public LoggingSystemProperties loggingSystemProperties(Environment environment) {

417

return new LoggingSystemProperties(environment);

418

}

419

420

@PostConstruct

421

public void configureLogging() {

422

// Apply custom log levels from properties

423

LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());

424

425

loggingProperties.getLevel().forEach((logger, level) -> {

426

System.out.println("Setting log level for " + logger + " to " + level);

427

loggingSystem.setLogLevel(logger, level);

428

});

429

}

430

}

431

```

432

433

### Environment Post Processors for Logging

434

435

Post-processors that can modify the environment before logging system initialization.

436

437

```java { .api }

438

/**

439

* EnvironmentPostProcessor to configure logging based on the Environment

440

*/

441

public class LoggingApplicationListener implements ApplicationListener<ApplicationEvent>,

442

Ordered, EnvironmentPostProcessor {

443

444

/**

445

* The default order for the LoggingApplicationListener

446

*/

447

public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 20;

448

449

/**

450

* The name of the Spring property that contains the name of the log file

451

*/

452

public static final String CONFIG_PROPERTY = "logging.config";

453

454

/**

455

* The name of the Spring property that controls the registration of a shutdown hook

456

* to shut down the logging system when the JVM exits

457

*/

458

public static final String REGISTER_SHUTDOWN_HOOK_PROPERTY = "logging.register-shutdown-hook";

459

460

@Override

461

public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

462

// Configure logging system properties from environment

463

configureLoggingSystem(environment);

464

}

465

466

@Override

467

public void onApplicationEvent(ApplicationEvent event) {

468

if (event instanceof ApplicationStartingEvent) {

469

onApplicationStartingEvent((ApplicationStartingEvent) event);

470

} else if (event instanceof ApplicationEnvironmentPreparedEvent) {

471

onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);

472

} else if (event instanceof ApplicationPreparedEvent) {

473

onApplicationPreparedEvent((ApplicationPreparedEvent) event);

474

} else if (event instanceof ContextClosedEvent) {

475

onContextClosedEvent((ContextClosedEvent) event);

476

} else if (event instanceof ApplicationFailedEvent) {

477

onApplicationFailedEvent((ApplicationFailedEvent) event);

478

}

479

}

480

481

private void onApplicationStartingEvent(ApplicationStartingEvent event) {

482

this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());

483

this.loggingSystem.beforeInitialize();

484

}

485

486

private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {

487

ConfigurableEnvironment environment = event.getEnvironment();

488

if (this.loggingSystem != null) {

489

initializeSystem(environment, this.loggingSystem, event.getSpringApplication());

490

}

491

}

492

}

493

```

494

495

**Usage Examples:**

496

497

```java

498

// Custom environment post-processor for logging

499

public class CustomLoggingEnvironmentPostProcessor implements EnvironmentPostProcessor {

500

501

@Override

502

public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

503

// Add logging-related properties based on active profiles

504

String[] activeProfiles = environment.getActiveProfiles();

505

506

Properties loggingProps = new Properties();

507

508

if (Arrays.asList(activeProfiles).contains("dev")) {

509

// Development logging configuration

510

loggingProps.put("logging.level.org.springframework", "DEBUG");

511

loggingProps.put("logging.level.com.example", "DEBUG");

512

loggingProps.put("logging.pattern.console", "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");

513

} else if (Arrays.asList(activeProfiles).contains("prod")) {

514

// Production logging configuration

515

loggingProps.put("logging.level.org.springframework", "WARN");

516

loggingProps.put("logging.level.com.example", "INFO");

517

loggingProps.put("logging.file.name", "/var/log/myapp/application.log");

518

loggingProps.put("logging.file.max-size", "100MB");

519

loggingProps.put("logging.file.max-history", "30");

520

}

521

522

if (!loggingProps.isEmpty()) {

523

PropertiesPropertySource propertySource = new PropertiesPropertySource(

524

"customLoggingProperties", loggingProps);

525

environment.getPropertySources().addLast(propertySource);

526

}

527

}

528

}

529

530

// Register the post-processor in spring.factories

531

// META-INF/spring.factories:

532

// org.springframework.boot.env.EnvironmentPostProcessor=\

533

// com.example.CustomLoggingEnvironmentPostProcessor

534

```

535

536

### Conditional Logging Configuration

537

538

Utilities for conditionally applying logging configuration based on environment conditions.

539

540

```java { .api }

541

/**

542

* Condition that matches when a logging system is available on the classpath

543

*/

544

public class LoggingSystemCondition extends SpringBootCondition {

545

546

@Override

547

public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {

548

String loggingSystem = System.getProperty(LoggingSystem.SYSTEM_PROPERTY);

549

if (LoggingSystem.NONE.equals(loggingSystem)) {

550

return ConditionOutcome.noMatch("Logging system is disabled");

551

}

552

553

if (LoggingSystem.get(context.getClassLoader()) != null) {

554

return ConditionOutcome.match("Logging system found on classpath");

555

}

556

557

return ConditionOutcome.noMatch("No logging system found on classpath");

558

}

559

}

560

```

561

562

**Usage Examples:**

563

564

```java

565

// Conditional logging beans

566

@Configuration

567

public class ConditionalLoggingConfiguration {

568

569

@Bean

570

@ConditionalOnProperty(name = "logging.structured.enabled", havingValue = "true")

571

public StructuredLoggingConfigurer structuredLoggingConfigurer() {

572

return new StructuredLoggingConfigurer();

573

}

574

575

@Bean

576

@ConditionalOnClass(name = "ch.qos.logback.classic.Logger")

577

public LogbackConfigurationCustomizer logbackCustomizer() {

578

return configuration -> {

579

// Custom Logback configuration

580

configuration.setLevel("org.springframework.security", Level.DEBUG);

581

};

582

}

583

584

@Bean

585

@ConditionalOnMissingBean(LoggingMetrics.class)

586

public LoggingMetrics loggingMetrics() {

587

return new LoggingMetrics();

588

}

589

}

590

591

// Custom structured logging

592

public class StructuredLoggingConfigurer {

593

594

@EventListener

595

public void configureStructuredLogging(ApplicationEnvironmentPreparedEvent event) {

596

ConfigurableEnvironment environment = event.getEnvironment();

597

598

// Configure JSON logging pattern

599

System.setProperty("logging.pattern.console",

600

"{\"timestamp\":\"%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}\",\"level\":\"%level\"," +

601

"\"thread\":\"%thread\",\"logger\":\"%logger\",\"message\":\"%msg\"}%n");

602

}

603

}

604

```