0
# Configuration and Logging
1
2
Logging configuration and general flake8 setup functionality for controlling output verbosity, log formatting, and accessing version information.
3
4
## Capabilities
5
6
### Logging Configuration
7
8
Configure flake8's internal logging system for debugging and monitoring execution.
9
10
```python { .api }
11
def configure_logging(verbosity: int, filename: str | None = None, logformat: str = LOG_FORMAT) -> None:
12
"""
13
Configure logging for flake8 execution.
14
15
Sets up logging handlers, formatters, and levels for flake8's internal
16
logging system. Useful for debugging flake8 behavior and plugin execution.
17
18
Parameters:
19
verbosity: Logging verbosity level
20
- 0 or less: No logging (disabled)
21
- 1: INFO level logging (general information)
22
- 2 or more: DEBUG level logging (detailed debugging)
23
24
filename: Log output destination
25
- None: Log to stderr (default)
26
- "stdout": Log to stdout
27
- "stderr": Log to stderr explicitly
28
- Any other string: Log to file with that path
29
30
logformat: Log message format string using Python logging format
31
Default uses LOG_FORMAT constant with process info and timestamps
32
33
Example:
34
# Enable debug logging to file
35
configure_logging(2, filename="flake8-debug.log")
36
37
# Enable info logging to stdout
38
configure_logging(1, filename="stdout")
39
"""
40
```
41
42
Usage example:
43
44
```python
45
import flake8
46
from flake8.api import legacy
47
48
# Enable debug logging for troubleshooting
49
flake8.configure_logging(
50
verbosity=2,
51
filename="flake8-debug.log"
52
)
53
54
# Now run flake8 - all debug info will be logged
55
style_guide = legacy.get_style_guide()
56
report = style_guide.check_files(['myproject/'])
57
```
58
59
### Version Information
60
61
Access flake8 version information for compatibility checking and reporting.
62
63
```python { .api }
64
__version__: str
65
"""
66
Current flake8 version string.
67
68
String containing the semantic version of the installed flake8 package
69
in format "MAJOR.MINOR.PATCH" (e.g., "7.3.0").
70
71
Example:
72
print(f"Using flake8 version: {flake8.__version__}")
73
"""
74
75
__version_info__: tuple[int, ...]
76
"""
77
Version information as tuple of integers.
78
79
Tuple containing version components as integers for programmatic
80
version comparison and compatibility checking.
81
82
Example:
83
if flake8.__version_info__ >= (7, 0, 0):
84
# Use features available in flake8 7.0+
85
"""
86
87
LOG_FORMAT: str
88
"""
89
Default log format string for flake8 logging.
90
91
Format string used by configure_logging() when no custom format is provided.
92
Includes process name, relative timestamps, log level, and message.
93
94
Default format includes:
95
- Logger name (25 chars)
96
- Process name (11 chars)
97
- Relative creation time (6 digits)
98
- Log level (8 chars)
99
- Log message
100
101
Example format:
102
"%(name)-25s %(processName)-11s %(relativeCreated)6d %(levelname)-8s %(message)s"
103
"""
104
```
105
106
Usage example:
107
108
```python
109
import flake8
110
111
# Check version compatibility
112
def check_flake8_compatibility():
113
"""Check if flake8 version meets requirements."""
114
115
required_version = (7, 0, 0)
116
current_version = flake8.__version_info__
117
118
if current_version >= required_version:
119
print(f"✅ Flake8 {flake8.__version__} meets requirements")
120
return True
121
else:
122
print(f"❌ Flake8 {flake8.__version__} is too old")
123
print(f" Required: {'.'.join(map(str, required_version))}+")
124
return False
125
126
# Report version info
127
def report_environment():
128
"""Report flake8 environment information."""
129
130
print(f"Flake8 Version: {flake8.__version__}")
131
print(f"Version Info: {flake8.__version_info__}")
132
print(f"Log Format: {flake8.LOG_FORMAT}")
133
134
if __name__ == "__main__":
135
report_environment()
136
check_flake8_compatibility()
137
```
138
139
## Logging Integration Examples
140
141
### Debug Mode
142
143
```python
144
import flake8
145
from flake8.api import legacy
146
import tempfile
147
import os
148
149
def debug_flake8_execution(files_to_check):
150
"""Run flake8 with detailed debugging information."""
151
152
# Create temporary debug log file
153
with tempfile.NamedTemporaryFile(mode='w', suffix='.log', delete=False) as f:
154
debug_log = f.name
155
156
try:
157
# Enable maximum verbosity
158
flake8.configure_logging(
159
verbosity=2,
160
filename=debug_log,
161
logformat="[%(asctime)s] %(name)s - %(levelname)s - %(message)s"
162
)
163
164
print(f"Debug logging enabled: {debug_log}")
165
166
# Run flake8 with debugging
167
style_guide = legacy.get_style_guide(show_source=True)
168
report = style_guide.check_files(files_to_check)
169
170
print(f"Execution complete. Found {report.total_errors} violations.")
171
172
# Display debug log contents
173
print("\n=== Debug Log Contents ===")
174
with open(debug_log, 'r') as f:
175
print(f.read())
176
177
finally:
178
# Clean up debug log
179
if os.path.exists(debug_log):
180
os.unlink(debug_log)
181
182
# Usage
183
debug_flake8_execution(['problematic_file.py'])
184
```
185
186
### Custom Log Analysis
187
188
```python
189
import flake8
190
from flake8.api import legacy
191
import logging
192
import io
193
194
class FlakeLogAnalyzer:
195
"""Capture and analyze flake8 log output."""
196
197
def __init__(self):
198
self.log_stream = io.StringIO()
199
self.handler = None
200
201
def start_capture(self):
202
"""Start capturing flake8 log output."""
203
204
# Configure flake8 logging to capture in memory
205
flake8.configure_logging(
206
verbosity=2,
207
filename=None # This will use stderr, but we'll redirect
208
)
209
210
# Add our custom handler to capture logs
211
logger = logging.getLogger('flake8')
212
self.handler = logging.StreamHandler(self.log_stream)
213
self.handler.setLevel(logging.DEBUG)
214
logger.addHandler(self.handler)
215
216
def stop_capture(self):
217
"""Stop capturing and return log contents."""
218
219
if self.handler:
220
logger = logging.getLogger('flake8')
221
logger.removeHandler(self.handler)
222
223
log_contents = self.log_stream.getvalue()
224
self.log_stream.close()
225
return log_contents
226
227
def run_with_analysis(self, files):
228
"""Run flake8 and analyze log output."""
229
230
self.start_capture()
231
232
try:
233
# Run flake8
234
style_guide = legacy.get_style_guide()
235
report = style_guide.check_files(files)
236
237
# Analyze logs
238
logs = self.stop_capture()
239
240
# Simple analysis
241
log_lines = logs.split('\n')
242
error_lines = [line for line in log_lines if 'ERROR' in line]
243
warning_lines = [line for line in log_lines if 'WARNING' in line]
244
245
print(f"Execution Results:")
246
print(f" Violations found: {report.total_errors}")
247
print(f" Log errors: {len(error_lines)}")
248
print(f" Log warnings: {len(warning_lines)}")
249
250
if error_lines:
251
print("\nLog Errors:")
252
for error in error_lines:
253
print(f" {error}")
254
255
return report, logs
256
257
except Exception as e:
258
self.stop_capture()
259
raise e
260
261
# Usage
262
analyzer = FlakeLogAnalyzer()
263
report, logs = analyzer.run_with_analysis(['myproject/'])
264
```
265
266
### Production Logging
267
268
```python
269
import flake8
270
from flake8.api import legacy
271
import logging.handlers
272
import os
273
274
def setup_production_logging(log_dir="/var/log/flake8"):
275
"""Set up production-ready flake8 logging."""
276
277
# Ensure log directory exists
278
os.makedirs(log_dir, exist_ok=True)
279
280
# Configure rotating log files
281
log_file = os.path.join(log_dir, "flake8.log")
282
283
# Set up flake8 logging with custom format
284
custom_format = (
285
"[%(asctime)s] %(name)s - %(levelname)s - "
286
"PID:%(process)d - %(message)s"
287
)
288
289
flake8.configure_logging(
290
verbosity=1, # INFO level for production
291
filename=log_file,
292
logformat=custom_format
293
)
294
295
# Also add rotating handler for long-term storage
296
logger = logging.getLogger('flake8')
297
298
rotating_handler = logging.handlers.RotatingFileHandler(
299
log_file, maxBytes=10*1024*1024, backupCount=5
300
)
301
rotating_handler.setFormatter(logging.Formatter(custom_format))
302
logger.addHandler(rotating_handler)
303
304
print(f"Production logging configured: {log_file}")
305
306
def production_quality_check(project_paths):
307
"""Run flake8 with production logging."""
308
309
setup_production_logging()
310
311
try:
312
style_guide = legacy.get_style_guide(
313
show_source=False, # Reduce log noise in production
314
statistics=False
315
)
316
317
total_violations = 0
318
for path in project_paths:
319
print(f"Checking {path}...")
320
report = style_guide.check_files([path])
321
total_violations += report.total_errors
322
323
print(f"Total violations across all projects: {total_violations}")
324
return total_violations == 0
325
326
except Exception as e:
327
logging.error(f"Quality check failed: {e}")
328
return False
329
330
# Usage
331
success = production_quality_check(['project1/', 'project2/'])
332
if not success:
333
print("Quality check failed - see logs for details")
334
```