0
# Logging Operations
1
2
Access to browser logs including console messages, network logs, and other diagnostic information using Chrome DevTools Protocol v110.
3
4
## Capabilities
5
6
### Log Domain Wrapper
7
8
High-level interface for CDP logging functionality providing type-safe access to browser logging operations.
9
10
```java { .api }
11
/**
12
* Log domain implementation for CDP v110 logging operations
13
*/
14
public class v110Log implements org.openqa.selenium.devtools.idealized.log.Log {
15
/**
16
* Initialize log domain (no parameters required)
17
*/
18
public v110Log();
19
}
20
```
21
22
### Log Domain Control
23
24
Enable and disable browser logging to start collecting log entries.
25
26
```java { .api }
27
/**
28
* Enable log domain to start collecting entries
29
* @return Command to enable logging
30
*/
31
public Command<Void> enable();
32
33
/**
34
* Clear all collected log entries
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.v110.v110Log;
44
45
v110Log log = new v110Log();
46
47
// Enable logging
48
devTools.send(log.enable());
49
50
// Navigate to page that generates logs
51
driver.get("https://example.com");
52
53
// Clear logs if needed
54
devTools.send(log.clear());
55
```
56
57
### Log Entry Monitoring
58
59
Monitor browser log entries as they are generated with detailed event information.
60
61
```java { .api }
62
/**
63
* Get log entry added events
64
* @return Event stream for log entries
65
*/
66
public Event<org.openqa.selenium.devtools.idealized.log.model.LogEntry> entryAdded();
67
```
68
69
**Usage Example:**
70
71
```java
72
import org.openqa.selenium.devtools.idealized.log.model.LogEntry;
73
import org.openqa.selenium.logging.LogEntry as SeleniumLogEntry;
74
75
// Enable logging
76
devTools.send(log.enable());
77
78
// Add log entry listener
79
devTools.addListener(log.entryAdded(), logEntry -> {
80
String source = logEntry.getSource();
81
SeleniumLogEntry seleniumEntry = logEntry.getEntry();
82
83
System.out.println("Log Source: " + source);
84
System.out.println("Level: " + seleniumEntry.getLevel());
85
System.out.println("Timestamp: " + new Date(seleniumEntry.getTimestamp()));
86
System.out.println("Message: " + seleniumEntry.getMessage());
87
System.out.println("---");
88
});
89
90
// Navigate to trigger log generation
91
driver.get("https://example.com");
92
```
93
94
### Log Level Conversion
95
96
Internal conversion between CDP and Java logging levels for proper log categorization.
97
98
```java { .api }
99
/**
100
* Convert CDP log level to Java logging level
101
* @param level CDP log level
102
* @return Java logging Level
103
*/
104
private Level fromCdpLevel(LogEntry.Level level);
105
106
/**
107
* Convert CDP timestamp to Java timestamp
108
* @param timestamp CDP timestamp
109
* @return Java timestamp in milliseconds
110
*/
111
private long fromCdpTimestamp(Timestamp timestamp);
112
```
113
114
## CDP Domain Classes
115
116
### Log Domain
117
118
Direct access to CDP Log domain for low-level logging operations.
119
120
```java { .api }
121
import org.openqa.selenium.devtools.v110.log.Log;
122
123
/**
124
* Enable log domain
125
*/
126
public static Command<Void> enable();
127
128
/**
129
* Disable log domain
130
*/
131
public static Command<Void> disable();
132
133
/**
134
* Clear browser logs
135
*/
136
public static Command<Void> clear();
137
138
/**
139
* Start violations reporting
140
*/
141
public static Command<Void> startViolationsReporting(List<ViolationSetting> config);
142
143
/**
144
* Stop violations reporting
145
*/
146
public static Command<Void> stopViolationsReporting();
147
148
/**
149
* Log entry added event
150
*/
151
public static Event<EntryAdded> entryAdded();
152
```
153
154
## Model Classes
155
156
### Log Entry Models
157
158
```java { .api }
159
import org.openqa.selenium.devtools.v110.log.model.*;
160
import org.openqa.selenium.devtools.idealized.log.model.*;
161
import org.openqa.selenium.logging.LogEntry;
162
import java.util.logging.Level;
163
164
/**
165
* CDP log entry
166
*/
167
public class org.openqa.selenium.devtools.v110.log.model.LogEntry {
168
/**
169
* Log source (console, network, security, etc.)
170
*/
171
LogEntrySource getSource();
172
173
/**
174
* Log level (verbose, info, warning, error)
175
*/
176
LogEntryLevel getLevel();
177
178
/**
179
* Log message text
180
*/
181
String getText();
182
183
/**
184
* Log entry timestamp
185
*/
186
Timestamp getTimestamp();
187
188
/**
189
* Source URL if applicable
190
*/
191
Optional<String> getUrl();
192
193
/**
194
* Line number in source if applicable
195
*/
196
Optional<Integer> getLineNumber();
197
198
/**
199
* Stack trace if applicable
200
*/
201
Optional<StackTrace> getStackTrace();
202
203
/**
204
* Network request ID if from network source
205
*/
206
Optional<NetworkRequestId> getNetworkRequestId();
207
208
/**
209
* Worker ID if from worker source
210
*/
211
Optional<String> getWorkerId();
212
213
/**
214
* Additional arguments
215
*/
216
Optional<List<RemoteObject>> getArgs();
217
}
218
219
/**
220
* Idealized log entry (high-level)
221
*/
222
public class org.openqa.selenium.devtools.idealized.log.model.LogEntry {
223
/**
224
* Log source as string
225
*/
226
String getSource();
227
228
/**
229
* Selenium log entry with standard format
230
*/
231
LogEntry getEntry();
232
}
233
234
/**
235
* Log entry source enumeration
236
*/
237
public enum LogEntrySource {
238
XML, JAVASCRIPT, NETWORK, STORAGE, APPCACHE, RENDERING,
239
SECURITY, DEPRECATION, WORKER, VIOLATION, INTERVENTION,
240
RECOMMENDATION, OTHER
241
}
242
243
/**
244
* Log entry level enumeration
245
*/
246
public enum LogEntryLevel {
247
VERBOSE, INFO, WARNING, ERROR
248
}
249
```
250
251
### Event Models
252
253
```java { .api }
254
/**
255
* Log entry added event
256
*/
257
public class EntryAdded {
258
/**
259
* The log entry that was added
260
*/
261
org.openqa.selenium.devtools.v110.log.model.LogEntry getEntry();
262
}
263
264
/**
265
* Violation setting for performance monitoring
266
*/
267
public class ViolationSetting {
268
/**
269
* Violation type name
270
*/
271
String getName();
272
273
/**
274
* Threshold value in milliseconds
275
*/
276
Number getThreshold();
277
}
278
```
279
280
### Supporting Models
281
282
```java { .api }
283
import org.openqa.selenium.devtools.v110.runtime.model.Timestamp;
284
import org.openqa.selenium.devtools.v110.runtime.model.StackTrace;
285
import org.openqa.selenium.devtools.v110.runtime.model.RemoteObject;
286
287
/**
288
* Network request identifier
289
*/
290
public class NetworkRequestId {
291
String toString();
292
}
293
294
/**
295
* CDP timestamp
296
*/
297
public class Timestamp {
298
Number toJson();
299
String toString();
300
}
301
```
302
303
## Advanced Usage Examples
304
305
### Comprehensive Log Processing
306
307
```java
308
v110Log log = new v110Log();
309
devTools.send(log.enable());
310
311
// Process different types of log entries
312
devTools.addListener(log.entryAdded(), logEntry -> {
313
String source = logEntry.getSource();
314
LogEntry seleniumEntry = logEntry.getEntry();
315
Level level = seleniumEntry.getLevel();
316
String message = seleniumEntry.getMessage();
317
318
// Process based on source
319
switch (source.toLowerCase()) {
320
case "console":
321
processConsoleLog(level, message);
322
break;
323
case "network":
324
processNetworkLog(level, message);
325
break;
326
case "security":
327
processSecurityLog(level, message);
328
break;
329
case "javascript":
330
processJavaScriptLog(level, message);
331
break;
332
default:
333
processGenericLog(source, level, message);
334
}
335
});
336
337
// Navigate and observe logs
338
driver.get("https://example.com");
339
```
340
341
### Error Log Filtering
342
343
```java
344
// Filter and handle only error-level logs
345
devTools.addListener(log.entryAdded(), logEntry -> {
346
LogEntry seleniumEntry = logEntry.getEntry();
347
348
if (seleniumEntry.getLevel().equals(Level.SEVERE)) {
349
System.err.println("ERROR LOG DETECTED:");
350
System.err.println("Source: " + logEntry.getSource());
351
System.err.println("Message: " + seleniumEntry.getMessage());
352
System.err.println("Time: " + new Date(seleniumEntry.getTimestamp()));
353
354
// Take screenshot or other diagnostic action
355
if (logEntry.getSource().equals("javascript")) {
356
takeScreenshotOnError();
357
}
358
}
359
});
360
```
361
362
### Performance Violation Monitoring
363
364
```java
365
import org.openqa.selenium.devtools.v110.log.model.ViolationSetting;
366
367
// Set up performance violation monitoring
368
List<ViolationSetting> violationSettings = Arrays.asList(
369
new ViolationSetting("longTask", 50), // Long tasks > 50ms
370
new ViolationSetting("longLayout", 30), // Layout > 30ms
371
new ViolationSetting("blockedEvent", 100), // Blocked events > 100ms
372
new ViolationSetting("blockedParser", 100), // Blocked parser > 100ms
373
new ViolationSetting("handler", 150), // Event handlers > 150ms
374
new ViolationSetting("recurringHandler", 250) // Recurring handlers > 250ms
375
);
376
377
devTools.send(Log.startViolationsReporting(violationSettings));
378
379
// Monitor for performance violations in logs
380
devTools.addListener(log.entryAdded(), logEntry -> {
381
String message = logEntry.getEntry().getMessage();
382
if (logEntry.getSource().equals("violation")) {
383
System.out.println("PERFORMANCE VIOLATION: " + message);
384
385
// Parse violation details and take action
386
if (message.contains("longTask")) {
387
System.out.println("Long task detected - consider code splitting");
388
} else if (message.contains("longLayout")) {
389
System.out.println("Long layout detected - check CSS complexity");
390
}
391
}
392
});
393
```
394
395
### Network Log Analysis
396
397
```java
398
// Analyze network-related log entries
399
devTools.addListener(log.entryAdded(), logEntry -> {
400
if (logEntry.getSource().equals("network")) {
401
String message = logEntry.getEntry().getMessage();
402
Level level = logEntry.getEntry().getLevel();
403
404
// Check for common network issues
405
if (message.contains("ERR_CONNECTION_REFUSED")) {
406
System.err.println("Connection refused error detected");
407
} else if (message.contains("ERR_NAME_NOT_RESOLVED")) {
408
System.err.println("DNS resolution error detected");
409
} else if (message.contains("Mixed Content")) {
410
System.err.println("Mixed content security issue detected");
411
} else if (level.equals(Level.WARNING) && message.contains("CORS")) {
412
System.err.println("CORS issue detected: " + message);
413
}
414
}
415
});
416
```
417
418
### Structured Log Collection
419
420
```java
421
import java.util.concurrent.ConcurrentLinkedQueue;
422
import java.util.concurrent.atomic.AtomicInteger;
423
424
// Collect logs in structured format
425
ConcurrentLinkedQueue<StructuredLogEntry> collectedLogs = new ConcurrentLinkedQueue<>();
426
AtomicInteger errorCount = new AtomicInteger(0);
427
AtomicInteger warningCount = new AtomicInteger(0);
428
429
devTools.addListener(log.entryAdded(), logEntry -> {
430
String source = logEntry.getSource();
431
LogEntry seleniumEntry = logEntry.getEntry();
432
Level level = seleniumEntry.getLevel();
433
434
// Create structured log entry
435
StructuredLogEntry structured = new StructuredLogEntry(
436
source,
437
level,
438
seleniumEntry.getMessage(),
439
seleniumEntry.getTimestamp(),
440
driver.getCurrentUrl()
441
);
442
443
collectedLogs.offer(structured);
444
445
// Update counters
446
if (level.equals(Level.SEVERE)) {
447
errorCount.incrementAndGet();
448
} else if (level.equals(Level.WARNING)) {
449
warningCount.incrementAndGet();
450
}
451
});
452
453
// Later, analyze collected logs
454
public void analyzeLogs() {
455
System.out.println("Total logs collected: " + collectedLogs.size());
456
System.out.println("Errors: " + errorCount.get());
457
System.out.println("Warnings: " + warningCount.get());
458
459
// Group by source
460
Map<String, List<StructuredLogEntry>> logsBySource = collectedLogs.stream()
461
.collect(Collectors.groupingBy(StructuredLogEntry::getSource));
462
463
logsBySource.forEach((source, logs) -> {
464
System.out.println(source + ": " + logs.size() + " entries");
465
});
466
}
467
468
// Helper class for structured logging
469
class StructuredLogEntry {
470
private final String source;
471
private final Level level;
472
private final String message;
473
private final long timestamp;
474
private final String url;
475
476
public StructuredLogEntry(String source, Level level, String message, long timestamp, String url) {
477
this.source = source;
478
this.level = level;
479
this.message = message;
480
this.timestamp = timestamp;
481
this.url = url;
482
}
483
484
// Getters...
485
public String getSource() { return source; }
486
public Level getLevel() { return level; }
487
public String getMessage() { return message; }
488
public long getTimestamp() { return timestamp; }
489
public String getUrl() { return url; }
490
}
491
```
492
493
## Error Handling
494
495
Logging operations may encounter various error conditions:
496
497
```java
498
import org.openqa.selenium.devtools.DevToolsException;
499
500
// Handle log domain enablement failures
501
try {
502
devTools.send(log.enable());
503
} catch (DevToolsException e) {
504
System.err.println("Failed to enable logging: " + e.getMessage());
505
// Continue without logging
506
}
507
508
// Handle log processing errors
509
devTools.addListener(log.entryAdded(), logEntry -> {
510
try {
511
processLogEntry(logEntry);
512
} catch (Exception e) {
513
System.err.println("Error processing log entry: " + e.getMessage());
514
// Continue processing other entries
515
}
516
});
517
518
// Handle violations reporting failures
519
try {
520
devTools.send(Log.startViolationsReporting(violationSettings));
521
} catch (DevToolsException e) {
522
System.err.println("Failed to start violations reporting: " + e.getMessage());
523
// Continue without performance violation monitoring
524
}
525
```