0
# Enhanced Logging
1
2
Comprehensive logging functionality built on Python's standard logging module with additional features including verbosity control, conditional logging, structured output formatting, and integration with the absl flag system.
3
4
## Capabilities
5
6
### Basic Logging Functions
7
8
Core logging functions for different severity levels with printf-style formatting support.
9
10
```python { .api }
11
def debug(msg, *args, **kwargs):
12
"""
13
Log a debug message.
14
15
Args:
16
msg (str): Message format string
17
*args: Arguments for string formatting
18
**kwargs: Additional logging arguments (exc_info, extra, etc.)
19
"""
20
21
def info(msg, *args, **kwargs):
22
"""
23
Log an info message.
24
25
Args:
26
msg (str): Message format string
27
*args: Arguments for string formatting
28
**kwargs: Additional logging arguments
29
"""
30
31
def warning(msg, *args, **kwargs):
32
"""
33
Log a warning message.
34
35
Args:
36
msg (str): Message format string
37
*args: Arguments for string formatting
38
**kwargs: Additional logging arguments
39
"""
40
41
def warn(msg, *args, **kwargs):
42
"""Alias for warning() function."""
43
44
def error(msg, *args, **kwargs):
45
"""
46
Log an error message.
47
48
Args:
49
msg (str): Message format string
50
*args: Arguments for string formatting
51
**kwargs: Additional logging arguments
52
"""
53
54
def fatal(msg, *args, **kwargs):
55
"""
56
Log a fatal message and exit the program.
57
58
Args:
59
msg (str): Message format string
60
*args: Arguments for string formatting
61
**kwargs: Additional logging arguments
62
63
Note: This function calls sys.exit(1) after logging the message.
64
"""
65
66
def exception(msg, *args, exc_info=True, **kwargs):
67
"""
68
Log an exception message with traceback information.
69
70
Args:
71
msg (str): Message format string
72
*args: Arguments for string formatting
73
exc_info (bool): Include exception information (default True)
74
**kwargs: Additional logging arguments
75
"""
76
```
77
78
### Generic Logging
79
80
General-purpose logging function for any severity level.
81
82
```python { .api }
83
def log(level, msg, *args, **kwargs):
84
"""
85
Log a message at the specified level.
86
87
Args:
88
level (int): Logging level (DEBUG, INFO, WARNING, ERROR, FATAL)
89
msg (str): Message format string
90
*args: Arguments for string formatting
91
**kwargs: Additional logging arguments
92
"""
93
```
94
95
### Verbosity Control
96
97
Functions for controlling logging verbosity and checking current verbosity settings.
98
99
```python { .api }
100
def get_verbosity():
101
"""
102
Get the current verbosity level.
103
104
Returns:
105
int: Current verbosity level
106
"""
107
108
def set_verbosity(v):
109
"""
110
Set the logging verbosity level.
111
112
Args:
113
v (int): Verbosity level (DEBUG=10, INFO=20, WARNING=30, ERROR=40, FATAL=50)
114
"""
115
116
def set_stderrthreshold(s):
117
"""
118
Set the stderr threshold level.
119
120
Messages at or above this level will be printed to stderr.
121
122
Args:
123
s (int): Stderr threshold level
124
"""
125
```
126
127
### Level Checking Functions
128
129
Functions to check if logging is enabled at specific levels for performance optimization.
130
131
```python { .api }
132
def level_debug():
133
"""
134
Check if debug level logging is enabled.
135
136
Returns:
137
bool: True if debug logging is enabled
138
"""
139
140
def level_info():
141
"""
142
Check if info level logging is enabled.
143
144
Returns:
145
bool: True if info logging is enabled
146
"""
147
148
def level_warning():
149
"""
150
Check if warning level logging is enabled.
151
152
Returns:
153
bool: True if warning logging is enabled
154
"""
155
156
def level_error():
157
"""
158
Check if error level logging is enabled.
159
160
Returns:
161
bool: True if error logging is enabled
162
"""
163
```
164
165
### Verbose Logging (vlog)
166
167
Per-file verbose logging system for fine-grained debug output control.
168
169
```python { .api }
170
def vlog(level, msg, *args, **kwargs):
171
"""
172
Log a verbose message at the specified level.
173
174
Verbose logging allows different verbosity levels per source file,
175
controlled by the --v flag and --vmodule flag.
176
177
Args:
178
level (int): Verbose level (higher numbers = more verbose)
179
msg (str): Message format string
180
*args: Arguments for string formatting
181
**kwargs: Additional logging arguments
182
"""
183
184
def vlog_is_on(level):
185
"""
186
Check if verbose logging is enabled at the specified level.
187
188
Args:
189
level (int): Verbose level to check
190
191
Returns:
192
bool: True if verbose logging is enabled at this level
193
"""
194
```
195
196
### Conditional Logging
197
198
Logging functions that only output messages under specific conditions to reduce log spam.
199
200
```python { .api }
201
def log_every_n(level, msg, n, *args, use_call_stack=False):
202
"""
203
Log a message every N times this function is called.
204
205
Args:
206
level (int): Logging level
207
msg (str): Message format string
208
n (int): Log every N calls
209
*args: Arguments for string formatting
210
use_call_stack (bool): Use call stack location for counting
211
"""
212
213
def log_every_n_seconds(level, msg, n_seconds, *args, use_call_stack=False):
214
"""
215
Log a message at most once every N seconds.
216
217
Args:
218
level (int): Logging level
219
msg (str): Message format string
220
n_seconds (float): Minimum time between log messages
221
*args: Arguments for string formatting
222
use_call_stack (bool): Use call stack location for timing
223
"""
224
225
def log_first_n(level, msg, n, *args, use_call_stack=False):
226
"""
227
Log a message only for the first N times this function is called.
228
229
Args:
230
level (int): Logging level
231
msg (str): Message format string
232
n (int): Number of times to log
233
*args: Arguments for string formatting
234
use_call_stack (bool): Use call stack location for counting
235
"""
236
237
def log_if(level, msg, condition, *args):
238
"""
239
Log a message only if the condition is true.
240
241
Args:
242
level (int): Logging level
243
msg (str): Message format string
244
condition (bool): Condition to check
245
*args: Arguments for string formatting
246
"""
247
```
248
249
### Utility Functions
250
251
Additional logging utilities for flushing output and internal operations.
252
253
```python { .api }
254
def flush():
255
"""Flush all logging output to ensure messages are written."""
256
257
def get_log_file_name(level=INFO):
258
"""
259
Get the log file name for the specified level.
260
261
Args:
262
level (int): Logging level
263
264
Returns:
265
str: Log file name or empty string if logging to stderr
266
"""
267
268
def find_log_dir_and_names(program_name=None, log_dir=None):
269
"""
270
Find log directory and construct log file names.
271
272
Args:
273
program_name (str): Name of the program (defaults to sys.argv[0])
274
log_dir (str): Log directory (defaults to /tmp or system temp)
275
276
Returns:
277
tuple: (log_dir, log_name, log_path)
278
"""
279
280
def find_log_dir(log_dir=None):
281
"""
282
Find the appropriate log directory.
283
284
Args:
285
log_dir (str): Preferred log directory
286
287
Returns:
288
str: Log directory path
289
"""
290
291
def get_absl_log_prefix(record):
292
"""
293
Get the standard absl log prefix for a record.
294
295
Args:
296
record (logging.LogRecord): Log record
297
298
Returns:
299
str: Formatted log prefix
300
"""
301
302
def skip_log_prefix(func):
303
"""
304
Decorator to skip log prefix for a function.
305
306
Args:
307
func: Function to decorate
308
309
Returns:
310
Decorated function
311
"""
312
313
def get_absl_logger():
314
"""
315
Get the absl logger instance.
316
317
Returns:
318
ABSLLogger: The absl logger
319
"""
320
321
def get_absl_handler():
322
"""
323
Get the absl log handler.
324
325
Returns:
326
ABSLHandler: The absl log handler
327
"""
328
329
def use_python_logging(quiet=False):
330
"""
331
Configure absl to use Python's standard logging.
332
333
Args:
334
quiet (bool): If True, don't print conversion message
335
"""
336
337
def use_absl_handler():
338
"""Configure absl to use its own log handler."""
339
```
340
341
### Handler and Formatter Classes
342
343
Advanced logging classes for custom log handling and formatting.
344
345
```python { .api }
346
class ABSLLogger(logging.Logger):
347
"""
348
Enhanced logger class with absl-specific functionality.
349
350
Extends Python's standard Logger with absl features like
351
frame skipping and fatal message handling.
352
"""
353
354
def findCaller(self, stack_info=False, stacklevel=1):
355
"""Find the caller of the logging function."""
356
357
def fatal(self, msg, *args, **kwargs):
358
"""Log a fatal message and exit."""
359
360
@classmethod
361
def register_frame_to_skip(cls, file_name, function_name, line_number=None):
362
"""
363
Register a stack frame to skip when finding caller.
364
365
Args:
366
file_name (str): File name to skip
367
function_name (str): Function name to skip
368
line_number (int): Optional line number
369
"""
370
371
class ABSLHandler(logging.Handler):
372
"""
373
Main absl log handler that manages log output routing.
374
375
Routes log messages to appropriate destinations (stderr, files)
376
based on configuration and integrates with Python logging.
377
"""
378
379
@property
380
def python_handler(self):
381
"""Get the underlying Python handler."""
382
383
def activate_python_handler(self):
384
"""Activate the Python logging handler."""
385
386
def use_absl_log_file(self, program_name=None, log_dir=None):
387
"""Configure logging to use absl log files."""
388
389
def start_logging_to_file(self, program_name=None, log_dir=None):
390
"""Start logging to a file."""
391
392
class PythonHandler(logging.StreamHandler):
393
"""
394
Stream handler with absl-specific enhancements.
395
396
Handles log output to streams (stderr, files) with absl
397
formatting and file rotation capabilities.
398
"""
399
400
def start_logging_to_file(self, program_name=None, log_dir=None):
401
"""Start logging to a file."""
402
403
def use_absl_log_file(self, program_name=None, log_dir=None):
404
"""Use absl-style log file naming."""
405
406
def flush(self):
407
"""Flush the handler output."""
408
409
class PythonFormatter(logging.Formatter):
410
"""
411
Custom formatter for absl log messages.
412
413
Formats log messages with absl-style prefixes including
414
severity, timestamp, thread ID, and source location.
415
"""
416
417
def format(self, record):
418
"""
419
Format a log record.
420
421
Args:
422
record (logging.LogRecord): Record to format
423
424
Returns:
425
str: Formatted log message
426
"""
427
```
428
429
## Logging Levels
430
431
Standard logging levels are available as constants:
432
433
```python { .api }
434
# Logging level constants (from Python's logging module)
435
DEBUG = 10
436
INFO = 20
437
WARNING = 30
438
ERROR = 40
439
FATAL = 50
440
```
441
442
## Usage Examples
443
444
### Basic Logging
445
446
```python
447
from absl import logging
448
449
# Configure logging verbosity
450
logging.set_verbosity(logging.INFO)
451
452
# Basic logging calls
453
logging.debug('This will not be shown (below INFO level)')
454
logging.info('Application started')
455
logging.warning('This is a warning message')
456
logging.error('An error occurred')
457
458
# String formatting
459
name = 'Alice'
460
age = 30
461
logging.info('User %s is %d years old', name, age)
462
```
463
464
### Performance-Optimized Logging
465
466
```python
467
from absl import logging
468
469
# Check level before expensive operations
470
if logging.level_debug():
471
expensive_debug_info = compute_expensive_debug_info()
472
logging.debug('Debug info: %s', expensive_debug_info)
473
474
# Verbose logging with level checking
475
if logging.vlog_is_on(2):
476
detailed_state = get_detailed_system_state()
477
logging.vlog(2, 'System state: %s', detailed_state)
478
```
479
480
### Conditional Logging
481
482
```python
483
from absl import logging
484
485
# Log every 100 iterations to avoid log spam
486
for i in range(1000):
487
process_item(i)
488
logging.log_every_n(logging.INFO, 'Processed %d items', 100, i + 1)
489
490
# Log at most once per minute
491
while running:
492
check_system_health()
493
logging.log_every_n_seconds(logging.INFO, 'System health check complete', 60)
494
495
# Log only first few occurrences
496
for item in items:
497
if item.has_warning():
498
logging.log_first_n(logging.WARNING, 'Item warning: %s', 5, item.warning)
499
```
500
501
### Exception Logging
502
503
```python
504
from absl import logging
505
506
try:
507
risky_operation()
508
except Exception as e:
509
# Log exception with traceback
510
logging.exception('Operation failed: %s', str(e))
511
512
# Or log error without traceback
513
logging.error('Operation failed: %s', str(e))
514
```
515
516
### Verbosity Configuration
517
518
```python
519
from absl import app
520
from absl import flags
521
from absl import logging
522
523
FLAGS = flags.FLAGS
524
525
# The logging module automatically defines these flags:
526
# --v (verbosity level)
527
# --vmodule (per-module verbosity)
528
# --logtostderr (log to stderr)
529
# --alsologtostderr (also log to stderr)
530
# --log_dir (log directory)
531
532
def main(argv):
533
# Verbosity is automatically configured from flags
534
logging.info('Application started with verbosity: %d', logging.get_verbosity())
535
536
# Verbose logging (controlled by --v flag)
537
logging.vlog(1, 'Level 1 verbose message')
538
logging.vlog(2, 'Level 2 verbose message (more detailed)')
539
540
if __name__ == '__main__':
541
app.run(main)
542
```
543
544
### Fatal Logging
545
546
```python
547
from absl import logging
548
549
def validate_config(config):
550
if not config.get('required_field'):
551
# This will log the error and exit with code 1
552
logging.fatal('Configuration missing required field: required_field')
553
554
# This line will never be reached if the above condition is true
555
logging.info('Configuration validated successfully')
556
```