or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bean-container.mdbean-invocation.mdbuild-profiles.mdbuild-properties.mdindex.mdinterceptor-integration.mdlogger-injection.mdruntime-lookup.md

logger-injection.mddocs/

0

# Logger Injection

1

2

CDI-based logger injection with support for custom logger names and automatic bean-specific logger creation. Quarkus Arc provides seamless integration with JBoss Logging through CDI qualifiers.

3

4

## Capabilities

5

6

### LoggerName Qualifier

7

8

CDI qualifier annotation for injecting loggers with custom names.

9

10

```java { .api }

11

/**

12

* CDI qualifier for injecting loggers with custom names.

13

*/

14

@Qualifier

15

@Retention(RetentionPolicy.RUNTIME)

16

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })

17

public @interface LoggerName {

18

/**

19

* The logger name must not be empty.

20

* @return the logger name

21

*/

22

@Nonbinding

23

String value();

24

25

/**

26

* Supports inline instantiation of this qualifier.

27

*/

28

public static final class Literal extends AnnotationLiteral<LoggerName> implements LoggerName {

29

private static final long serialVersionUID = 1L;

30

private final String value;

31

32

public Literal(String value);

33

public String value();

34

}

35

}

36

```

37

38

**Usage Examples:**

39

40

```java

41

import jakarta.enterprise.context.ApplicationScoped;

42

import jakarta.inject.Inject;

43

import io.quarkus.arc.log.LoggerName;

44

import org.jboss.logging.Logger;

45

46

@ApplicationScoped

47

public class UserService {

48

49

// Default logger - uses the class name as logger name

50

@Inject

51

Logger defaultLogger;

52

53

// Custom named logger

54

@Inject

55

@LoggerName("user.operations")

56

Logger operationsLogger;

57

58

// Another custom logger for security events

59

@Inject

60

@LoggerName("security.audit")

61

Logger securityLogger;

62

63

public void createUser(String username) {

64

defaultLogger.info("Creating user: " + username);

65

operationsLogger.debug("User creation operation started");

66

securityLogger.info("New user account created: " + username);

67

}

68

69

public void deleteUser(String username) {

70

defaultLogger.warn("Deleting user: " + username);

71

securityLogger.warn("User account deleted: " + username);

72

}

73

}

74

```

75

76

### Method Parameter Injection

77

78

Inject loggers as method parameters in producer methods or other CDI methods.

79

80

```java

81

import jakarta.enterprise.context.ApplicationScoped;

82

import jakarta.enterprise.inject.Produces;

83

import io.quarkus.arc.log.LoggerName;

84

import org.jboss.logging.Logger;

85

86

@ApplicationScoped

87

public class ServiceFactory {

88

89

@Produces

90

@ApplicationScoped

91

public DatabaseService createDatabaseService(

92

@LoggerName("database.operations") Logger dbLogger) {

93

return new DatabaseService(dbLogger);

94

}

95

96

@Produces

97

@ApplicationScoped

98

public CacheService createCacheService(

99

@LoggerName("cache.operations") Logger cacheLogger) {

100

return new CacheService(cacheLogger);

101

}

102

}

103

104

class DatabaseService {

105

private final Logger logger;

106

107

public DatabaseService(Logger logger) {

108

this.logger = logger;

109

}

110

111

public void performQuery(String sql) {

112

logger.debug("Executing query: " + sql);

113

// Database operation

114

logger.info("Query executed successfully");

115

}

116

}

117

118

class CacheService {

119

private final Logger logger;

120

121

public CacheService(Logger logger) {

122

this.logger = logger;

123

}

124

125

public void put(String key, Object value) {

126

logger.trace("Caching value for key: " + key);

127

// Cache operation

128

}

129

}

130

```

131

132

### Programmatic Logger Creation

133

134

Use the LoggerName.Literal class for programmatic logger creation.

135

136

```java

137

import jakarta.enterprise.context.ApplicationScoped;

138

import jakarta.inject.Inject;

139

import jakarta.enterprise.inject.Instance;

140

import io.quarkus.arc.log.LoggerName;

141

import org.jboss.logging.Logger;

142

143

@ApplicationScoped

144

public class DynamicLoggingService {

145

146

@Inject

147

Instance<Logger> loggerInstance;

148

149

public void logWithDynamicName(String loggerName, String message) {

150

// Create logger with dynamic name

151

Logger logger = loggerInstance

152

.select(new LoggerName.Literal(loggerName))

153

.get();

154

155

logger.info(message);

156

}

157

158

public void processModules(String[] modules) {

159

for (String module : modules) {

160

Logger moduleLogger = loggerInstance

161

.select(new LoggerName.Literal("module." + module))

162

.get();

163

164

moduleLogger.info("Processing module: " + module);

165

}

166

}

167

}

168

```

169

170

### Logger Categories and Hierarchies

171

172

Organize loggers using hierarchical naming patterns.

173

174

```java

175

import jakarta.enterprise.context.ApplicationScoped;

176

import jakarta.inject.Inject;

177

import io.quarkus.arc.log.LoggerName;

178

import org.jboss.logging.Logger;

179

180

@ApplicationScoped

181

public class OrderProcessingService {

182

183

// Main service logger

184

@Inject

185

@LoggerName("orders")

186

Logger ordersLogger;

187

188

// Validation subsystem

189

@Inject

190

@LoggerName("orders.validation")

191

Logger validationLogger;

192

193

// Payment subsystem

194

@Inject

195

@LoggerName("orders.payment")

196

Logger paymentLogger;

197

198

// Inventory subsystem

199

@Inject

200

@LoggerName("orders.inventory")

201

Logger inventoryLogger;

202

203

// Notification subsystem

204

@Inject

205

@LoggerName("orders.notifications")

206

Logger notificationLogger;

207

208

public void processOrder(Order order) {

209

ordersLogger.info("Processing order: " + order.getId());

210

211

try {

212

validateOrder(order);

213

processPayment(order);

214

updateInventory(order);

215

sendNotifications(order);

216

217

ordersLogger.info("Order processing completed: " + order.getId());

218

} catch (Exception e) {

219

ordersLogger.error("Order processing failed: " + order.getId(), e);

220

throw e;

221

}

222

}

223

224

private void validateOrder(Order order) {

225

validationLogger.debug("Validating order: " + order.getId());

226

// Validation logic

227

validationLogger.info("Order validation passed: " + order.getId());

228

}

229

230

private void processPayment(Order order) {

231

paymentLogger.debug("Processing payment for order: " + order.getId());

232

// Payment logic

233

paymentLogger.info("Payment processed: " + order.getId());

234

}

235

236

private void updateInventory(Order order) {

237

inventoryLogger.debug("Updating inventory for order: " + order.getId());

238

// Inventory logic

239

inventoryLogger.info("Inventory updated: " + order.getId());

240

}

241

242

private void sendNotifications(Order order) {

243

notificationLogger.debug("Sending notifications for order: " + order.getId());

244

// Notification logic

245

notificationLogger.info("Notifications sent: " + order.getId());

246

}

247

}

248

249

class Order {

250

private String id;

251

// Other order fields

252

253

public String getId() { return id; }

254

public void setId(String id) { this.id = id; }

255

}

256

```

257

258

### Producer Method Integration

259

260

Create loggers in producer methods for dependency injection into non-CDI objects.

261

262

```java

263

import jakarta.enterprise.context.ApplicationScoped;

264

import jakarta.enterprise.inject.Produces;

265

import jakarta.enterprise.inject.spi.InjectionPoint;

266

import io.quarkus.arc.log.LoggerName;

267

import org.jboss.logging.Logger;

268

269

@ApplicationScoped

270

public class LoggerProducer {

271

272

@Produces

273

public Logger createClassLogger(InjectionPoint injectionPoint) {

274

// Create logger based on the injection point's class

275

return Logger.getLogger(injectionPoint.getMember().getDeclaringClass());

276

}

277

278

@Produces

279

@LoggerName("custom")

280

public Logger createCustomLogger() {

281

return Logger.getLogger("custom.application.logger");

282

}

283

}

284

285

// Usage in services

286

@ApplicationScoped

287

public class ProductService {

288

289

@Inject

290

Logger logger; // Will be created using class name

291

292

@Inject

293

@LoggerName("custom")

294

Logger customLogger;

295

296

public void manageProduct(String productId) {

297

logger.info("Managing product: " + productId);

298

customLogger.debug("Custom logging for product: " + productId);

299

}

300

}

301

```

302

303

### Integration with Configuration

304

305

Combine logger injection with configuration for dynamic logging behavior.

306

307

```java

308

import jakarta.enterprise.context.ApplicationScoped;

309

import jakarta.inject.Inject;

310

import org.eclipse.microprofile.config.inject.ConfigProperty;

311

import io.quarkus.arc.log.LoggerName;

312

import org.jboss.logging.Logger;

313

314

@ApplicationScoped

315

public class ConfigurableLoggingService {

316

317

@Inject

318

@LoggerName("app.performance")

319

Logger performanceLogger;

320

321

@Inject

322

@LoggerName("app.business")

323

Logger businessLogger;

324

325

@ConfigProperty(name = "logging.performance.enabled", defaultValue = "false")

326

boolean performanceLoggingEnabled;

327

328

@ConfigProperty(name = "logging.detailed", defaultValue = "false")

329

boolean detailedLogging;

330

331

public void performBusinessOperation(String operation) {

332

long startTime = System.currentTimeMillis();

333

334

if (detailedLogging) {

335

businessLogger.info("Starting business operation: " + operation);

336

}

337

338

try {

339

// Business logic here

340

Thread.sleep(100); // Simulate work

341

342

businessLogger.info("Completed business operation: " + operation);

343

} catch (Exception e) {

344

businessLogger.error("Business operation failed: " + operation, e);

345

throw new RuntimeException(e);

346

} finally {

347

if (performanceLoggingEnabled) {

348

long duration = System.currentTimeMillis() - startTime;

349

performanceLogger.info("Operation '" + operation + "' took " + duration + "ms");

350

}

351

}

352

}

353

}

354

```

355

356

## Logger Configuration

357

358

Configure logger levels and output through standard Quarkus logging configuration:

359

360

### Application Properties

361

362

```properties

363

# Root logger configuration

364

quarkus.log.level=INFO

365

quarkus.log.console.enable=true

366

367

# Custom logger categories

368

quarkus.log.category."user.operations".level=DEBUG

369

quarkus.log.category."security.audit".level=INFO

370

quarkus.log.category."orders".level=INFO

371

quarkus.log.category."orders.validation".level=DEBUG

372

quarkus.log.category."orders.payment".level=WARN

373

374

# Performance logging

375

quarkus.log.category."app.performance".level=INFO

376

377

# File output for specific categories

378

quarkus.log.category."security.audit".handlers=SECURITY_FILE

379

quarkus.log.handler.file.SECURITY_FILE.enable=true

380

quarkus.log.handler.file.SECURITY_FILE.path=security-audit.log

381

quarkus.log.handler.file.SECURITY_FILE.format=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c] %s%e%n

382

```

383

384

### Runtime Configuration

385

386

```properties

387

# Enable/disable performance logging at runtime

388

logging.performance.enabled=true

389

logging.detailed=false

390

```

391

392

## Best Practices

393

394

### Naming Conventions

395

396

```java

397

// Use hierarchical naming for related loggers

398

@LoggerName("app.module.component") // Good

399

@LoggerName("RandomLoggerName") // Avoid

400

401

// Examples of good logger names

402

@LoggerName("security.authentication")

403

@LoggerName("performance.database")

404

@LoggerName("integration.external-api")

405

@LoggerName("business.order-processing")

406

```

407

408

### Logger Organization

409

410

```java

411

@ApplicationScoped

412

public class WellOrganizedService {

413

414

// Main service logger

415

@Inject

416

Logger serviceLogger;

417

418

// Specialized loggers for different concerns

419

@Inject

420

@LoggerName("performance.metrics")

421

Logger metricsLogger;

422

423

@Inject

424

@LoggerName("security.access")

425

Logger securityLogger;

426

427

@Inject

428

@LoggerName("integration.third-party")

429

Logger integrationLogger;

430

}

431

```

432

433

### Error Handling

434

435

```java

436

@ApplicationScoped

437

public class ErrorHandlingExample {

438

439

@Inject

440

@LoggerName("errors.business")

441

Logger errorLogger;

442

443

public void handleBusinessOperation() {

444

try {

445

// Business logic

446

} catch (BusinessException e) {

447

errorLogger.warn("Business rule violation", e);

448

// Handle gracefully

449

} catch (Exception e) {

450

errorLogger.error("Unexpected error in business operation", e);

451

throw e;

452

}

453

}

454

}

455

```