or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

events.mdindex.mdjavascript.mdlogging.mdnetwork.mdtarget.md

logging.mddocs/

0

# Browser Logging

1

2

Browser log capture and management for the Chrome DevTools Protocol v85. This functionality allows you to access browser logs with different severity levels and timestamps for debugging and monitoring purposes.

3

4

## Capabilities

5

6

### V85Log Class

7

8

The main class for browser log management implementing the idealized Log interface.

9

10

```java { .api }

11

/**

12

* Browser logging functionality for Chrome DevTools v85

13

*/

14

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

15

/**

16

* Creates a new V85Log instance

17

*/

18

public V85Log();

19

}

20

```

21

22

### Log Control

23

24

Enable, disable, and clear browser logs.

25

26

```java { .api }

27

/**

28

* Enables browser log collection

29

* @return Command to enable logging

30

*/

31

public Command<Void> enable();

32

33

/**

34

* Clears all collected browser logs

35

* @return Command to clear logs

36

*/

37

public Command<Void> clear();

38

```

39

40

**Usage Example:**

41

42

```java

43

import org.openqa.selenium.devtools.v85.V85Log;

44

45

V85Log log = domains.log();

46

47

// Enable log collection

48

devTools.send(log.enable());

49

50

// Clear existing logs

51

devTools.send(log.clear());

52

```

53

54

### Log Event Monitoring

55

56

Monitor new log entries as they are added by the browser.

57

58

```java { .api }

59

/**

60

* Event fired when a new log entry is added

61

* @return Event for new log entries

62

*/

63

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

64

```

65

66

**Usage Example:**

67

68

```java

69

// Listen for new log entries

70

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

71

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

72

new Date(logEntry.getEntry().getTimestamp()),

73

logEntry.getEntry().getLevel(),

74

logEntry.getEntry().getMessage()

75

);

76

77

// Handle specific log levels

78

if (logEntry.getEntry().getLevel() == Level.SEVERE) {

79

handleSevereError(logEntry);

80

}

81

});

82

```

83

84

### Complete Logging Setup

85

86

```java

87

import org.openqa.selenium.chrome.ChromeDriver;

88

import org.openqa.selenium.devtools.DevTools;

89

import org.openqa.selenium.devtools.v85.V85Domains;

90

import java.util.logging.Level;

91

92

ChromeDriver driver = new ChromeDriver();

93

DevTools devTools = driver.getDevTools();

94

devTools.createSession();

95

96

V85Domains domains = new V85Domains(devTools);

97

V85Log log = domains.log();

98

99

// Enable logging

100

devTools.send(log.enable());

101

102

// Set up log monitoring

103

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

104

var entry = logEntry.getEntry();

105

106

// Format log message

107

String formattedLog = String.format(

108

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

109

new Date(entry.getTimestamp()),

110

logEntry.getSource(),

111

entry.getLevel(),

112

entry.getMessage()

113

);

114

115

// Route to appropriate handler based on level

116

switch (entry.getLevel()) {

117

case SEVERE:

118

System.err.println("ERROR: " + formattedLog);

119

logToErrorSystem(formattedLog);

120

break;

121

122

case WARNING:

123

System.out.println("WARN: " + formattedLog);

124

logToWarningSystem(formattedLog);

125

break;

126

127

case INFO:

128

System.out.println("INFO: " + formattedLog);

129

break;

130

131

case FINEST:

132

if (debugMode) {

133

System.out.println("DEBUG: " + formattedLog);

134

}

135

break;

136

137

default:

138

System.out.println("LOG: " + formattedLog);

139

}

140

});

141

142

// Navigate to page - logs will be captured

143

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

144

145

// Clear logs when needed

146

devTools.send(log.clear());

147

```

148

149

## Log Level Conversion

150

151

The V85Log class automatically converts Chrome DevTools Protocol log levels to Java logging levels:

152

153

```java { .api }

154

/**

155

* Converts CDP log level to Java logging level

156

* @param level - CDP log level

157

* @return Java logging Level

158

*/

159

private Level fromCdpLevel(LogEntry.Level level);

160

```

161

162

**Level Mapping:**

163

- `verbose``Level.FINEST`

164

- `info``Level.INFO`

165

- `warning``Level.WARNING`

166

- `error``Level.SEVERE`

167

- Default → `Level.INFO`

168

169

## Timestamp Handling

170

171

```java { .api }

172

/**

173

* Converts CDP timestamp to Java long timestamp

174

* @param timestamp - CDP timestamp

175

* @return Java timestamp in milliseconds, or current time if parsing fails

176

*/

177

private long fromCdpTimestamp(Timestamp timestamp);

178

```

179

180

## CDP Model Classes

181

182

### LogEntry (CDP)

183

184

Raw log entry from the Chrome DevTools Protocol.

185

186

```java { .api }

187

/**

188

* Log entry from Chrome DevTools Protocol

189

*/

190

public class LogEntry {

191

/**

192

* Gets the log message source

193

* @return Log source (e.g., "javascript", "network", "storage")

194

*/

195

public Source getSource();

196

197

/**

198

* Gets the log level

199

* @return Log severity level

200

*/

201

public Level getLevel();

202

203

/**

204

* Gets the log message text

205

* @return Log message content

206

*/

207

public String getText();

208

209

/**

210

* Gets the timestamp when the log was created

211

* @return Log timestamp

212

*/

213

public Timestamp getTimestamp();

214

215

/**

216

* Gets the URL where the log originated (if applicable)

217

* @return Source URL

218

*/

219

public Optional<String> getUrl();

220

221

/**

222

* Gets the line number where the log originated (if applicable)

223

* @return Line number in source

224

*/

225

public Optional<Integer> getLineNumber();

226

227

/**

228

* Gets the stack trace for the log entry (if applicable)

229

* @return Stack trace information

230

*/

231

public Optional<StackTrace> getStackTrace();

232

233

/**

234

* Log severity levels in CDP

235

*/

236

public enum Level {

237

VERBOSE, INFO, WARNING, ERROR

238

}

239

240

/**

241

* Log sources in CDP

242

*/

243

public enum Source {

244

XML, JAVASCRIPT, NETWORK, STORAGE, APPCACHE, RENDERING,

245

SECURITY, DEPRECATION, WORKER, VIOLATION, INTERVENTION,

246

RECOMMENDATION, OTHER

247

}

248

}

249

```

250

251

### LogEntry (Idealized)

252

253

Selenium's idealized log entry that wraps CDP log data.

254

255

```java { .api }

256

/**

257

* Selenium's idealized log entry wrapper

258

*/

259

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

260

/**

261

* Creates a new idealized log entry

262

* @param source - Log source as string

263

* @param entry - Java LogEntry with level, timestamp, and message

264

*/

265

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

266

267

/**

268

* Gets the log source

269

* @return Source of the log entry

270

*/

271

public String getSource();

272

273

/**

274

* Gets the wrapped Java log entry

275

* @return Java LogEntry with standard logging information

276

*/

277

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

278

}

279

```

280

281

### Selenium LogEntry

282

283

Standard Selenium log entry used by the idealized interface.

284

285

```java { .api }

286

/**

287

* Standard Selenium log entry

288

*/

289

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

290

/**

291

* Gets the log level

292

* @return Java logging Level

293

*/

294

public Level getLevel();

295

296

/**

297

* Gets the timestamp in milliseconds

298

* @return Timestamp when log was created

299

*/

300

public long getTimestamp();

301

302

/**

303

* Gets the log message

304

* @return Log message text

305

*/

306

public String getMessage();

307

}

308

```

309

310

## Advanced Log Filtering

311

312

```java

313

// Filter logs by source and level

314

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

315

String source = logEntry.getSource();

316

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

317

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

318

319

// Only process JavaScript errors and network issues

320

if (source.equals("javascript") && level == Level.SEVERE) {

321

handleJavaScriptError(logEntry);

322

} else if (source.equals("network") && (level == Level.WARNING || level == Level.SEVERE)) {

323

handleNetworkIssue(logEntry);

324

}

325

326

// Filter by message content

327

if (message.contains("404") || message.contains("Failed to load")) {

328

handleResourceError(logEntry);

329

}

330

});

331

332

// Batch log processing

333

private final List<LogEntry> logBuffer = new ArrayList<>();

334

private final Timer logProcessor = new Timer();

335

336

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

337

synchronized (logBuffer) {

338

logBuffer.add(logEntry);

339

340

// Process logs in batches every 5 seconds

341

if (logBuffer.size() == 1) {

342

logProcessor.schedule(new TimerTask() {

343

@Override

344

public void run() {

345

processBatchedLogs();

346

}

347

}, 5000);

348

}

349

}

350

});

351

352

private void processBatchedLogs() {

353

synchronized (logBuffer) {

354

if (!logBuffer.isEmpty()) {

355

// Process all buffered logs

356

logBuffer.forEach(this::processLogEntry);

357

logBuffer.clear();

358

}

359

}

360

}

361

```

362

363

## Log Persistence

364

365

```java

366

// Save logs to file

367

private final FileWriter logWriter = new FileWriter("browser-logs.txt", true);

368

369

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

370

try {

371

String logLine = String.format(

372

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

373

new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(logEntry.getEntry().getTimestamp())),

374

logEntry.getSource().toUpperCase(),

375

logEntry.getEntry().getLevel(),

376

logEntry.getEntry().getMessage()

377

);

378

379

logWriter.write(logLine);

380

logWriter.flush();

381

} catch (IOException e) {

382

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

383

}

384

});

385

386

// Remember to close the writer when done

387

// logWriter.close();

388

```