or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

events.mdindex.mdjavascript.mdlogging.mdnetwork.mdtargets.md

logging.mddocs/

0

# Log Management

1

2

Browser console and log event collection with level filtering and timestamp handling for comprehensive logging support. Provides access to browser-side logging events for monitoring and debugging web applications.

3

4

## Capabilities

5

6

### Log Handler

7

8

Creates a log management handler for Chrome DevTools Protocol v99.

9

10

```java { .api }

11

/**

12

* Log management implementation for CDP v99

13

* Implements the idealized Log interface

14

*/

15

public class V99Log implements org.openqa.selenium.devtools.idealized.log.Log;

16

```

17

18

### Log Domain Control

19

20

Enable and disable browser log collection.

21

22

```java { .api }

23

/**

24

* Enable log domain for collecting browser logs

25

* @return Command to enable log collection

26

*/

27

public Command<Void> enable();

28

29

/**

30

* Clear all browser console logs

31

* @return Command to clear logs

32

*/

33

public Command<Void> clear();

34

```

35

36

### Log Event Monitoring

37

38

Monitor browser log entries as they are generated.

39

40

```java { .api }

41

/**

42

* Get event handler for new log entries

43

* @return Event for log entry additions

44

*/

45

public Event<LogEntry> entryAdded();

46

```

47

48

## Protocol Types

49

50

### Log Entry

51

52

```java { .api }

53

/**

54

* Browser log entry from CDP

55

*/

56

public class LogEntry {

57

/**

58

* Get log entry source (console, network, etc.)

59

* @return Log source

60

*/

61

public LogSource getSource();

62

63

/**

64

* Get log level (verbose, info, warning, error)

65

* @return Log level

66

*/

67

public Level getLevel();

68

69

/**

70

* Get log message text

71

* @return Message string

72

*/

73

public String getText();

74

75

/**

76

* Get timestamp when log entry was created

77

* @return Timestamp

78

*/

79

public Timestamp getTimestamp();

80

81

/**

82

* Get URL where log entry originated

83

* @return Optional URL

84

*/

85

public Optional<String> getUrl();

86

87

/**

88

* Get line number where log entry originated

89

* @return Optional line number

90

*/

91

public Optional<Integer> getLineNumber();

92

93

/**

94

* Get stack trace if available

95

* @return Optional stack trace

96

*/

97

public Optional<StackTrace> getStackTrace();

98

99

/**

100

* Get network request ID if log is network-related

101

* @return Optional network request ID

102

*/

103

public Optional<NetworkRequestId> getNetworkRequestId();

104

105

/**

106

* Get worker ID if log originated from web worker

107

* @return Optional worker ID

108

*/

109

public Optional<WorkerId> getWorkerId();

110

111

/**

112

* Get additional arguments for the log entry

113

* @return Optional list of remote objects

114

*/

115

public Optional<List<RemoteObject>> getArgs();

116

}

117

118

/**

119

* Log entry source types

120

*/

121

public enum LogSource {

122

XML("xml"),

123

JAVASCRIPT("javascript"),

124

NETWORK("network"),

125

STORAGE("storage"),

126

APPCACHE("appcache"),

127

RENDERING("rendering"),

128

SECURITY("security"),

129

DEPRECATION("deprecation"),

130

WORKER("worker"),

131

VIOLATION("violation"),

132

INTERVENTION("intervention"),

133

RECOMMENDATION("recommendation"),

134

OTHER("other");

135

}

136

137

/**

138

* Log level enumeration

139

*/

140

public enum Level {

141

VERBOSE("verbose"),

142

INFO("info"),

143

WARNING("warning"),

144

ERROR("error");

145

}

146

```

147

148

### Selenium Log Integration

149

150

```java { .api }

151

/**

152

* Selenium log entry (converted from CDP log entry)

153

*/

154

public class org.openqa.selenium.devtools.idealized.log.model.LogEntry {

155

/**

156

* Create Selenium log entry

157

* @param source - Log source string

158

* @param entry - Selenium logging LogEntry

159

*/

160

public LogEntry(String source, org.openqa.selenium.logging.LogEntry entry);

161

162

/**

163

* Get log source

164

* @return Source string

165

*/

166

public String getSource();

167

168

/**

169

* Get Selenium log entry

170

* @return Selenium LogEntry

171

*/

172

public org.openqa.selenium.logging.LogEntry getLogEntry();

173

}

174

175

/**

176

* Standard Selenium log entry

177

*/

178

public class org.openqa.selenium.logging.LogEntry {

179

/**

180

* Get log level

181

* @return Java logging Level

182

*/

183

public Level getLevel();

184

185

/**

186

* Get timestamp in milliseconds

187

* @return Timestamp

188

*/

189

public long getTimestamp();

190

191

/**

192

* Get log message

193

* @return Message string

194

*/

195

public String getMessage();

196

}

197

```

198

199

## Implementation Details

200

201

### Level Conversion

202

203

The V99Log implementation converts CDP log levels to Java logging levels:

204

205

```java { .api }

206

/**

207

* Convert CDP log level to Java logging level

208

* @param level - CDP log level

209

* @return Java logging Level

210

*/

211

private Level fromCdpLevel(LogEntry.Level level);

212

```

213

214

**Level Mapping:**

215

- `verbose``Level.FINEST`

216

- `info``Level.INFO`

217

- `warning``Level.WARNING`

218

- `error``Level.SEVERE`

219

- unknown → `Level.INFO` (default)

220

221

### Timestamp Conversion

222

223

```java { .api }

224

/**

225

* Convert CDP timestamp to milliseconds

226

* @param timestamp - CDP timestamp

227

* @return Milliseconds since epoch

228

*/

229

private long fromCdpTimestamp(Timestamp timestamp);

230

```

231

232

## Usage Examples

233

234

### Basic Log Monitoring

235

236

```java

237

import org.openqa.selenium.devtools.DevTools;

238

import org.openqa.selenium.devtools.v99.V99Domains;

239

import org.openqa.selenium.logging.LogEntry;

240

241

DevTools devTools = ...; // from ChromeDriver

242

V99Domains domains = new V99Domains(devTools);

243

244

// Enable log collection

245

devTools.send(domains.log().enable());

246

247

// Listen for log entries

248

devTools.addListener(domains.log().entryAdded(), logEntry -> {

249

String source = logEntry.getSource();

250

LogEntry seleniumLogEntry = logEntry.getLogEntry();

251

252

System.out.printf("[%s] %s - %s: %s%n",

253

new Date(seleniumLogEntry.getTimestamp()),

254

source,

255

seleniumLogEntry.getLevel(),

256

seleniumLogEntry.getMessage()

257

);

258

});

259

260

// Navigate to page - logs will be captured

261

driver.get("https://example.com");

262

```

263

264

### Log Level Filtering

265

266

```java

267

devTools.send(domains.log().enable());

268

269

devTools.addListener(domains.log().entryAdded(), logEntry -> {

270

LogEntry seleniumEntry = logEntry.getLogEntry();

271

Level level = seleniumEntry.getLevel();

272

273

// Only process warnings and errors

274

if (level == Level.WARNING || level == Level.SEVERE) {

275

System.err.printf("IMPORTANT: [%s] %s: %s%n",

276

logEntry.getSource(),

277

level,

278

seleniumEntry.getMessage()

279

);

280

281

// Could trigger alerts, save to special log, etc.

282

handleImportantLogEntry(logEntry);

283

}

284

});

285

```

286

287

### Source-Based Log Processing

288

289

```java

290

devTools.send(domains.log().enable());

291

292

devTools.addListener(domains.log().entryAdded(), logEntry -> {

293

String source = logEntry.getSource();

294

LogEntry seleniumEntry = logEntry.getLogEntry();

295

296

switch (source) {

297

case "network":

298

handleNetworkLog(seleniumEntry);

299

break;

300

case "javascript":

301

handleJavaScriptLog(seleniumEntry);

302

break;

303

case "security":

304

handleSecurityLog(seleniumEntry);

305

break;

306

case "deprecation":

307

handleDeprecationLog(seleniumEntry);

308

break;

309

default:

310

handleGenericLog(source, seleniumEntry);

311

}

312

});

313

314

private void handleNetworkLog(LogEntry entry) {

315

// Process network-related logs

316

if (entry.getLevel() == Level.SEVERE) {

317

System.err.println("Network Error: " + entry.getMessage());

318

}

319

}

320

321

private void handleSecurityLog(LogEntry entry) {

322

// Security logs are always important

323

System.err.println("SECURITY: " + entry.getMessage());

324

// Could trigger security alerts, audit logging, etc.

325

}

326

```

327

328

### Log Collection and Analysis

329

330

```java

331

import java.util.concurrent.ConcurrentLinkedQueue;

332

import java.util.Map;

333

import java.util.concurrent.ConcurrentHashMap;

334

335

// Collect logs for later analysis

336

Queue<org.openqa.selenium.devtools.idealized.log.model.LogEntry> collectedLogs =

337

new ConcurrentLinkedQueue<>();

338

Map<String, AtomicInteger> logCounts = new ConcurrentHashMap<>();

339

340

devTools.send(domains.log().enable());

341

342

devTools.addListener(domains.log().entryAdded(), logEntry -> {

343

// Collect all logs

344

collectedLogs.offer(logEntry);

345

346

// Count by source

347

String source = logEntry.getSource();

348

logCounts.computeIfAbsent(source, k -> new AtomicInteger(0)).incrementAndGet();

349

350

// Count by level

351

Level level = logEntry.getLogEntry().getLevel();

352

logCounts.computeIfAbsent(level.toString(), k -> new AtomicInteger(0)).incrementAndGet();

353

});

354

355

// After test execution, analyze collected logs

356

public void analyzeLogs() {

357

System.out.println("Log Analysis:");

358

System.out.println("Total logs: " + collectedLogs.size());

359

360

logCounts.forEach((key, count) -> {

361

System.out.println(key + ": " + count.get());

362

});

363

364

// Find all error-level logs

365

List<org.openqa.selenium.devtools.idealized.log.model.LogEntry> errors =

366

collectedLogs.stream()

367

.filter(entry -> entry.getLogEntry().getLevel() == Level.SEVERE)

368

.collect(Collectors.toList());

369

370

if (!errors.isEmpty()) {

371

System.err.println("Found " + errors.size() + " error-level logs:");

372

errors.forEach(error -> {

373

System.err.println(" " + error.getSource() + ": " +

374

error.getLogEntry().getMessage());

375

});

376

}

377

}

378

```

379

380

### Log Clearing

381

382

```java

383

// Clear logs before starting a test

384

devTools.send(domains.log().clear());

385

devTools.send(domains.log().enable());

386

387

// Perform test operations

388

performTestSteps();

389

390

// Clear logs between test phases

391

devTools.send(domains.log().clear());

392

393

// Continue with next test phase

394

performNextTestPhase();

395

```

396

397

### Integration with Selenium Logging

398

399

```java

400

import org.openqa.selenium.logging.LogType;

401

import org.openqa.selenium.logging.LoggingPreferences;

402

import org.openqa.selenium.chrome.ChromeOptions;

403

404

// Configure Chrome logging preferences

405

LoggingPreferences loggingPrefs = new LoggingPreferences();

406

loggingPrefs.enable(LogType.BROWSER, Level.ALL);

407

loggingPrefs.enable(LogType.PERFORMANCE, Level.INFO);

408

409

ChromeOptions options = new ChromeOptions();

410

options.setCapability("goog:loggingPrefs", loggingPrefs);

411

412

WebDriver driver = new ChromeDriver(options);

413

414

// Use both DevTools log monitoring and standard Selenium logs

415

DevTools devTools = ((ChromeDriver) driver).getDevTools();

416

devTools.createSession();

417

418

V99Domains domains = new V99Domains(devTools);

419

devTools.send(domains.log().enable());

420

421

// DevTools log monitoring (real-time)

422

devTools.addListener(domains.log().entryAdded(), logEntry -> {

423

// Real-time log processing

424

processLogEntryRealTime(logEntry);

425

});

426

427

// Standard Selenium log retrieval (after page load)

428

LogEntries browserLogs = driver.manage().logs().get(LogType.BROWSER);

429

for (LogEntry entry : browserLogs) {

430

// Process accumulated logs

431

processLogEntryBatch(entry);

432

}

433

```

434

435

## Error Handling

436

437

Log management operations can encounter various issues:

438

439

- **Log domain not enabled**: Enable log domain before monitoring

440

- **High log volume**: Filter logs to prevent overwhelming the system

441

- **Memory issues**: Large numbers of collected logs can consume memory

442

- **Timestamp parsing**: Invalid timestamps fall back to current time

443

444

Handle errors through proper exception handling and resource management:

445

446

```java

447

try {

448

devTools.send(domains.log().enable());

449

450

// Set up log monitoring

451

setupLogMonitoring();

452

453

// Perform operations

454

runTestOperations();

455

456

} catch (DevToolsException e) {

457

System.err.println("Failed to enable log monitoring: " + e.getMessage());

458

} finally {

459

// Note: CDP Log domain doesn't have explicit disable

460

// It's cleaned up when DevTools session ends

461

}

462

```

463

464

## Performance Considerations

465

466

- **Log volume**: High-frequency applications can generate many log entries

467

- **Memory usage**: Collecting logs consumes memory; clear periodically if needed

468

- **Processing overhead**: Log event handlers should be efficient

469

- **Network impact**: Remote debugging increases log-related network traffic

470

- **Storage**: Long-running tests may need log rotation or cleanup strategies