0
# Logging and Monitoring
1
2
Advanced logging system with support for multiple visualization backends including TensorBoard, Weights & Biases, MLflow, ClearML, Neptune, and others with structured message passing and history tracking. The system provides comprehensive monitoring capabilities for training processes.
3
4
## Capabilities
5
6
### MMLogger Class
7
8
Advanced logger with enhanced features for machine learning workflows.
9
10
```python { .api }
11
class MMLogger:
12
@staticmethod
13
def get_instance(name: str, logger_name: str = None) -> 'MMLogger':
14
"""
15
Get logger instance (singleton pattern).
16
17
Parameters:
18
- name: Logger instance name
19
- logger_name: Actual logger name
20
21
Returns:
22
MMLogger instance
23
"""
24
25
@staticmethod
26
def get_current_instance() -> 'MMLogger':
27
"""
28
Get current logger instance.
29
30
Returns:
31
Current MMLogger instance
32
"""
33
34
def info(self, message: str):
35
"""
36
Log info message.
37
38
Parameters:
39
- message: Message to log
40
"""
41
42
def warning(self, message: str):
43
"""
44
Log warning message.
45
46
Parameters:
47
- message: Warning message to log
48
"""
49
50
def error(self, message: str):
51
"""
52
Log error message.
53
54
Parameters:
55
- message: Error message to log
56
"""
57
58
def debug(self, message: str):
59
"""
60
Log debug message.
61
62
Parameters:
63
- message: Debug message to log
64
"""
65
66
def critical(self, message: str):
67
"""
68
Log critical message.
69
70
Parameters:
71
- message: Critical message to log
72
"""
73
74
def log(self, level: int, message: str):
75
"""
76
Log message at specified level.
77
78
Parameters:
79
- level: Logging level
80
- message: Message to log
81
"""
82
83
@property
84
def name(self) -> str:
85
"""Logger name."""
86
87
@property
88
def logger(self):
89
"""Underlying logger instance."""
90
```
91
92
### MessageHub Class
93
94
Central hub for message passing and metric tracking between components.
95
96
```python { .api }
97
class MessageHub:
98
@classmethod
99
def get_instance(cls, name: str = 'mmengine') -> 'MessageHub':
100
"""
101
Get MessageHub instance (singleton pattern).
102
103
Parameters:
104
- name: Instance name
105
106
Returns:
107
MessageHub instance
108
"""
109
110
@classmethod
111
def get_current_instance(cls) -> 'MessageHub':
112
"""
113
Get current MessageHub instance.
114
115
Returns:
116
Current MessageHub instance
117
"""
118
119
def update_scalar(self, key: str, value: float, count: int = 1):
120
"""
121
Update scalar value.
122
123
Parameters:
124
- key: Scalar key name
125
- value: Scalar value
126
- count: Count for averaging
127
"""
128
129
def update_scalars(self, scalar_dict: dict, count: int = 1):
130
"""
131
Update multiple scalar values.
132
133
Parameters:
134
- scalar_dict: Dictionary of scalar values
135
- count: Count for averaging
136
"""
137
138
def get_scalar(self, key: str):
139
"""
140
Get scalar value.
141
142
Parameters:
143
- key: Scalar key name
144
145
Returns:
146
Scalar value and statistics
147
"""
148
149
def get_scalars(self, keys: list) -> dict:
150
"""
151
Get multiple scalar values.
152
153
Parameters:
154
- keys: List of scalar keys
155
156
Returns:
157
Dictionary of scalar values
158
"""
159
160
def update_info(self, key: str, value):
161
"""
162
Update info value.
163
164
Parameters:
165
- key: Info key name
166
- value: Info value
167
"""
168
169
def get_info(self, key: str):
170
"""
171
Get info value.
172
173
Parameters:
174
- key: Info key name
175
176
Returns:
177
Info value
178
"""
179
180
def log_scalars(self, scalar_dict: dict, step: int):
181
"""
182
Log scalars to all backends.
183
184
Parameters:
185
- scalar_dict: Dictionary of scalars to log
186
- step: Step number
187
"""
188
189
def clear(self):
190
"""Clear all stored data."""
191
192
@property
193
def log_scalars_keys(self) -> set:
194
"""Get all scalar keys."""
195
```
196
197
### HistoryBuffer Class
198
199
Buffer for storing and managing training history with statistical calculations.
200
201
```python { .api }
202
class HistoryBuffer:
203
def __init__(self, max_length: int = 1000000):
204
"""
205
Initialize history buffer.
206
207
Parameters:
208
- max_length: Maximum buffer length
209
"""
210
211
def update(self, value: float, count: int = 1):
212
"""
213
Update buffer with new value.
214
215
Parameters:
216
- value: Value to add
217
- count: Count for weighted update
218
"""
219
220
def mean(self, window_size: int = None) -> float:
221
"""
222
Calculate mean value.
223
224
Parameters:
225
- window_size: Window size for calculation
226
227
Returns:
228
Mean value
229
"""
230
231
def current(self) -> float:
232
"""
233
Get current (latest) value.
234
235
Returns:
236
Current value
237
"""
238
239
def max(self, window_size: int = None) -> float:
240
"""
241
Get maximum value.
242
243
Parameters:
244
- window_size: Window size for calculation
245
246
Returns:
247
Maximum value
248
"""
249
250
def min(self, window_size: int = None) -> float:
251
"""
252
Get minimum value.
253
254
Parameters:
255
- window_size: Window size for calculation
256
257
Returns:
258
Minimum value
259
"""
260
261
def data(self) -> list:
262
"""
263
Get all data.
264
265
Returns:
266
List of all values
267
"""
268
269
def __len__(self) -> int:
270
"""Get buffer length."""
271
```
272
273
### Print Log Function
274
275
Convenient function for logging with automatic logger detection.
276
277
```python { .api }
278
def print_log(msg: str, logger: str = None, level: int = 20):
279
"""
280
Print log message with logger.
281
282
Parameters:
283
- msg: Message to log
284
- logger: Logger name or instance
285
- level: Logging level (INFO=20, WARNING=30, ERROR=40)
286
"""
287
```
288
289
### Log Processor
290
291
System for processing and formatting training logs.
292
293
```python { .api }
294
class LogProcessor:
295
def __init__(self, window_size: int = 10, by_epoch: bool = True, custom_cfg: list = None, num_digits: int = 4, log_with_hierarchy: bool = False):
296
"""
297
Initialize log processor.
298
299
Parameters:
300
- window_size: Window size for smoothing
301
- by_epoch: Whether to log by epoch
302
- custom_cfg: Custom logging configuration
303
- num_digits: Number of digits for formatting
304
- log_with_hierarchy: Whether to log with hierarchy
305
"""
306
307
def get_log_after_iter(self, runner, batch_idx: int, mode: str) -> dict:
308
"""
309
Get log information after iteration.
310
311
Parameters:
312
- runner: Runner instance
313
- batch_idx: Batch index
314
- mode: Training mode ('train', 'val', 'test')
315
316
Returns:
317
Dictionary of log information
318
"""
319
320
def get_log_after_epoch(self, runner, batch_idx: int, mode: str) -> dict:
321
"""
322
Get log information after epoch.
323
324
Parameters:
325
- runner: Runner instance
326
- batch_idx: Batch index
327
- mode: Training mode
328
329
Returns:
330
Dictionary of log information
331
"""
332
```
333
334
## Usage Examples
335
336
### Basic Logging
337
338
```python
339
from mmengine import MMLogger, print_log
340
341
# Get logger instance
342
logger = MMLogger.get_instance('my_logger')
343
344
# Log at different levels
345
logger.info('Training started')
346
logger.warning('Learning rate is very high')
347
logger.error('Training failed')
348
349
# Use convenient print_log function
350
print_log('This is an info message', level=20)
351
print_log('This is a warning', level=30)
352
```
353
354
### Message Hub for Metrics
355
356
```python
357
from mmengine import MessageHub
358
359
# Get message hub instance
360
message_hub = MessageHub.get_instance('training')
361
362
# Update scalar metrics
363
message_hub.update_scalar('loss', 0.5)
364
message_hub.update_scalar('accuracy', 0.95)
365
366
# Update multiple scalars
367
metrics = {'loss': 0.4, 'accuracy': 0.96, 'lr': 0.001}
368
message_hub.update_scalars(metrics)
369
370
# Get scalar values
371
loss_info = message_hub.get_scalar('loss')
372
all_metrics = message_hub.get_scalars(['loss', 'accuracy'])
373
```
374
375
### History Buffer for Statistics
376
377
```python
378
from mmengine.logging import HistoryBuffer
379
380
# Create history buffer
381
loss_buffer = HistoryBuffer(max_length=10000)
382
383
# Update with training losses
384
for epoch in range(100):
385
for batch_loss in batch_losses:
386
loss_buffer.update(batch_loss)
387
388
# Get statistics
389
avg_loss = loss_buffer.mean(window_size=100) # Last 100 values
390
current_loss = loss_buffer.current()
391
min_loss = loss_buffer.min()
392
max_loss = loss_buffer.max()
393
394
print(f'Epoch {epoch}: avg={avg_loss:.4f}, current={current_loss:.4f}')
395
```
396
397
### Integration with Training
398
399
```python
400
from mmengine import Runner, MMLogger, MessageHub
401
402
# Set up logging for training
403
logger = MMLogger.get_instance('training')
404
message_hub = MessageHub.get_instance('training')
405
406
# In training loop
407
def train_step(model, data, optimizer):
408
loss = model(data)
409
410
# Log to message hub
411
message_hub.update_scalar('train_loss', loss.item())
412
413
# Log important events
414
logger.info(f'Step loss: {loss.item():.4f}')
415
416
return loss
417
418
# Create runner with log processor
419
runner = Runner(
420
model=model,
421
log_processor=dict(
422
window_size=20,
423
by_epoch=True,
424
custom_cfg=[
425
dict(data_src='loss', window_size=10, method_name='mean'),
426
dict(data_src='accuracy', window_size=10, method_name='mean')
427
]
428
)
429
)
430
```
431
432
### Custom Logger Configuration
433
434
```python
435
import logging
436
from mmengine import MMLogger
437
438
# Create logger with custom configuration
439
logger = MMLogger.get_instance(
440
'custom_logger',
441
logger_name='my_training'
442
)
443
444
# Add custom handler
445
handler = logging.FileHandler('training.log')
446
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
447
handler.setFormatter(formatter)
448
logger.logger.addHandler(handler)
449
450
# Use logger
451
logger.info('Custom logging setup complete')
452
```
453
454
### Log Processing Configuration
455
456
```python
457
from mmengine.runner import LogProcessor
458
459
# Create custom log processor
460
log_processor = LogProcessor(
461
window_size=50,
462
by_epoch=True,
463
custom_cfg=[
464
dict(data_src='loss', window_size=20, method_name='mean'),
465
dict(data_src='loss', window_size=1, method_name='current'),
466
dict(data_src='accuracy', window_size=20, method_name='mean'),
467
dict(data_src='lr', method_name='current')
468
],
469
num_digits=6,
470
log_with_hierarchy=True
471
)
472
473
# Use in runner
474
runner = Runner(
475
model=model,
476
log_processor=log_processor
477
)
478
```