or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

console-logging.mddomain-management.mdindex.mdjavascript-execution.mdnetwork-operations.mdruntime-events.mdtarget-management.md

console-logging.mddocs/

0

# Console Log Management

1

2

Manages console log operations, log entries, and provides conversion between CDP log formats and Selenium's logging system. This domain enables comprehensive monitoring of browser console output including different log levels and sources.

3

4

## Capabilities

5

6

### V102Log Class

7

8

Main class for console log management. Implements the idealized Log interface to provide v102-specific implementations for log monitoring and entry processing.

9

10

```java { .api }

11

/**

12

* Manages console log operations and entries

13

*/

14

public class V102Log implements org.openqa.selenium.devtools.idealized.log.Log {

15

/**

16

* Enables the Log domain to start receiving log entries

17

* @return Command to enable log domain

18

*/

19

public Command<Void> enable();

20

21

/**

22

* Clears all existing log entries

23

* @return Command to clear log entries

24

*/

25

public Command<Void> clear();

26

27

/**

28

* Returns the log entry added event for monitoring new log entries

29

* @return Event for log entry notifications with idealized log entry format

30

*/

31

public Event<org.openqa.selenium.devtools.idealized.log.model.LogEntry> entryAdded();

32

}

33

```

34

35

**Usage Examples:**

36

37

### Basic Log Monitoring

38

39

```java

40

import org.openqa.selenium.chrome.ChromeDriver;

41

import org.openqa.selenium.devtools.DevTools;

42

import org.openqa.selenium.devtools.v102.V102Domains;

43

import org.openqa.selenium.devtools.idealized.log.model.LogEntry;

44

import java.util.logging.Level;

45

46

// Setup

47

ChromeDriver driver = new ChromeDriver();

48

DevTools devTools = driver.getDevTools();

49

devTools.createSession();

50

V102Domains domains = new V102Domains(devTools);

51

52

// Enable log domain

53

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

54

55

// Listen for log entries

56

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

57

System.out.println(String.format(

58

"[%s] %s: %s",

59

logEntry.getSource(),

60

logEntry.getEntry().getLevel(),

61

logEntry.getEntry().getMessage()

62

));

63

});

64

65

// Navigate to a page that generates console output

66

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

67

68

// Execute JavaScript that logs messages

69

driver.executeScript("console.log('This is an info message');");

70

driver.executeScript("console.warn('This is a warning message');");

71

driver.executeScript("console.error('This is an error message');");

72

73

// Clear log entries

74

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

75

76

// Cleanup

77

driver.quit();

78

```

79

80

### Log Level Filtering

81

82

```java

83

import java.util.logging.Level;

84

85

// Monitor only specific log levels

86

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

87

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

88

String message = logEntry.getEntry().getMessage();

89

String source = logEntry.getSource();

90

91

switch (level.getName()) {

92

case "SEVERE": // Error level

93

System.err.println("ERROR [" + source + "]: " + message);

94

break;

95

case "WARNING": // Warning level

96

System.out.println("WARN [" + source + "]: " + message);

97

break;

98

case "INFO": // Info level

99

System.out.println("INFO [" + source + "]: " + message);

100

break;

101

case "FINEST": // Verbose level

102

System.out.println("VERBOSE [" + source + "]: " + message);

103

break;

104

default:

105

System.out.println("LOG [" + source + "] " + level + ": " + message);

106

}

107

});

108

```

109

110

### Log Collection and Analysis

111

112

```java

113

import java.util.concurrent.CopyOnWriteArrayList;

114

import java.time.Instant;

115

116

// Collect logs for analysis

117

List<LogEntry> collectedLogs = new CopyOnWriteArrayList<>();

118

119

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

120

collectedLogs.add(logEntry);

121

122

// Analyze log patterns

123

String message = logEntry.getEntry().getMessage();

124

if (message.contains("error") || message.contains("failed")) {

125

System.err.println("Potential issue detected: " + message);

126

}

127

});

128

129

// Perform test actions

130

driver.get("https://complex-app.com");

131

// ... perform various actions ...

132

133

// Analyze collected logs

134

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

135

136

long errorCount = collectedLogs.stream()

137

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

138

.count();

139

140

long warningCount = collectedLogs.stream()

141

.filter(entry -> entry.getEntry().getLevel() == Level.WARNING)

142

.count();

143

144

System.out.println("Errors: " + errorCount + ", Warnings: " + warningCount);

145

146

// Clear collected logs for next test

147

collectedLogs.clear();

148

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

149

```

150

151

### Source-Based Log Filtering

152

153

```java

154

// Filter logs by source

155

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

156

String source = logEntry.getSource();

157

String message = logEntry.getEntry().getMessage();

158

159

switch (source) {

160

case "javascript":

161

System.out.println("JS: " + message);

162

break;

163

case "network":

164

System.out.println("NET: " + message);

165

break;

166

case "storage":

167

System.out.println("STORAGE: " + message);

168

break;

169

case "appcache":

170

System.out.println("APPCACHE: " + message);

171

break;

172

case "rendering":

173

System.out.println("RENDER: " + message);

174

break;

175

case "security":

176

System.out.println("SECURITY: " + message);

177

break;

178

case "deprecation":

179

System.out.println("DEPRECATED: " + message);

180

break;

181

case "worker":

182

System.out.println("WORKER: " + message);

183

break;

184

case "violation":

185

System.out.println("VIOLATION: " + message);

186

break;

187

case "intervention":

188

System.out.println("INTERVENTION: " + message);

189

break;

190

case "recommendation":

191

System.out.println("RECOMMENDATION: " + message);

192

break;

193

default:

194

System.out.println("OTHER [" + source + "]: " + message);

195

}

196

});

197

```

198

199

## Log Level Conversion

200

201

The V102Log class provides automatic conversion between CDP log levels and Java logging levels:

202

203

### CDP to Java Level Mapping

204

205

```java { .api }

206

/**

207

* Internal level conversion (handled automatically by V102Log)

208

*/

209

private Level fromCdpLevel(LogEntry.Level level) {

210

switch (level.toString()) {

211

case "verbose":

212

return Level.FINEST; // Most detailed

213

case "info":

214

return Level.INFO; // General information

215

case "warning":

216

return Level.WARNING; // Warning messages

217

case "error":

218

return Level.SEVERE; // Error messages

219

default:

220

return Level.INFO; // Default fallback

221

}

222

}

223

```

224

225

### Timestamp Handling

226

227

```java { .api }

228

/**

229

* Internal timestamp conversion (handled automatically by V102Log)

230

*/

231

private long fromCdpTimestamp(Timestamp timestamp) {

232

try {

233

return Long.parseLong(timestamp.toString());

234

} catch (NumberFormatException e) {

235

return System.currentTimeMillis(); // Fallback to current time

236

}

237

}

238

```

239

240

## CDP Protocol Classes

241

242

The V102Log class interacts with generated CDP protocol classes:

243

244

### Log Domain

245

246

```java { .api }

247

// Generated CDP log classes (available at runtime)

248

class Log {

249

static Command<Void> enable();

250

static Command<Void> clear();

251

static Event<LogEntry> entryAdded();

252

}

253

254

// CDP log entry representation

255

class LogEntry {

256

enum Level {

257

VERBOSE, INFO, WARNING, ERROR

258

}

259

260

String getSource();

261

Level getLevel();

262

String getText();

263

Timestamp getTimestamp();

264

Optional<String> getUrl();

265

Optional<Integer> getLineNumber();

266

Optional<StackTrace> getStackTrace();

267

}

268

269

// Timestamp representation

270

class Timestamp {

271

String toString();

272

JsonElement toJson();

273

}

274

```

275

276

### Selenium Integration Types

277

278

```java { .api }

279

// Idealized log entry for Selenium integration

280

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

281

/**

282

* Creates idealized log entry with source and standard log entry

283

*/

284

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

285

286

String getSource();

287

org.openqa.selenium.logging.LogEntry getEntry();

288

}

289

290

// Standard Selenium log entry

291

class org.openqa.selenium.logging.LogEntry {

292

LogEntry(Level level, long timestamp, String message);

293

294

Level getLevel();

295

long getTimestamp();

296

String getMessage();

297

}

298

299

// Java logging levels

300

enum Level {

301

FINEST, // Verbose

302

INFO, // Info

303

WARNING, // Warning

304

SEVERE // Error

305

}

306

```

307

308

### Event Processing Flow

309

310

The log processing follows this flow:

311

312

1. **CDP Log Entry**: Browser generates log entry with CDP-specific format

313

2. **Event Notification**: V102Log receives CDP LogEntry via entryAdded event

314

3. **Level Conversion**: CDP level converted to Java logging Level

315

4. **Timestamp Conversion**: CDP timestamp converted to milliseconds

316

5. **Idealized Entry**: Creates Selenium idealized LogEntry

317

6. **Event Dispatch**: Dispatches converted entry to listeners

318

319

## Advanced Log Management Patterns

320

321

### Log Buffering

322

323

```java

324

import java.util.concurrent.BlockingQueue;

325

import java.util.concurrent.LinkedBlockingQueue;

326

327

// Buffer logs for batch processing

328

BlockingQueue<LogEntry> logBuffer = new LinkedBlockingQueue<>();

329

330

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

331

logBuffer.offer(logEntry);

332

});

333

334

// Process logs in background thread

335

Thread logProcessor = new Thread(() -> {

336

while (!Thread.currentThread().isInterrupted()) {

337

try {

338

LogEntry entry = logBuffer.take(); // Blocks until available

339

processLogEntry(entry);

340

} catch (InterruptedException e) {

341

Thread.currentThread().interrupt();

342

break;

343

}

344

}

345

});

346

logProcessor.start();

347

```

348

349

### Log Persistence

350

351

```java

352

import java.io.FileWriter;

353

import java.io.IOException;

354

import java.time.Instant;

355

import java.time.format.DateTimeFormatter;

356

357

// Write logs to file

358

FileWriter logFile = new FileWriter("console-logs.txt", true);

359

360

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

361

try {

362

String timestamp = DateTimeFormatter.ISO_INSTANT

363

.format(Instant.ofEpochMilli(logEntry.getEntry().getTimestamp()));

364

365

String logLine = String.format(

366

"%s [%s] %s: %s%n",

367

timestamp,

368

logEntry.getSource(),

369

logEntry.getEntry().getLevel(),

370

logEntry.getEntry().getMessage()

371

);

372

373

logFile.write(logLine);

374

logFile.flush();

375

} catch (IOException e) {

376

System.err.println("Failed to write log entry: " + e.getMessage());

377

}

378

});

379

380

// Remember to close file when done

381

// logFile.close();

382

```

383

384

### Conditional Log Monitoring

385

386

```java

387

// Monitor logs only during specific operations

388

boolean monitoringEnabled = false;

389

390

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

391

if (monitoringEnabled) {

392

// Process log entry only when monitoring is enabled

393

handleLogEntry(logEntry);

394

}

395

});

396

397

// Enable monitoring for specific operation

398

monitoringEnabled = true;

399

driver.get("https://test-app.com");

400

performCriticalOperation();

401

monitoringEnabled = false;

402

403

// Clear logs after operation

404

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

405

```