Logging and Debugging
Effective logging and debugging are crucial for maintaining and improving Whisper2Linux. This section outlines the logging mechanisms implemented in the application and provides guidelines for debugging issues.
Logging System
Whisper2Linux uses Python's built-in logging
module for flexible and configurable logging.
Logging Levels
The application uses standard Python logging levels:
- DEBUG: Detailed information, typically of interest only when diagnosing problems.
- INFO: Confirmation that things are working as expected.
- WARNING: An indication that something unexpected happened, or indicative of some problem in the near future.
- ERROR: Due to a more serious problem, the software has not been able to perform some function.
- CRITICAL: A serious error, indicating that the program itself may be unable to continue running.
Configuring Logging
Logging can be configured using command-line arguments:
python whisper2linux.py --log memory
python whisper2linux.py --log file --log-file /path/to/logfile.log
Logging Implementation
The logging setup is handled in the setup_logging
function:
def setup_logging(log_type, log_file=None):
if log_type == 'none':
logging.disable(logging.CRITICAL)
elif log_type == 'memory':
log_stream = io.StringIO()
handler = StreamAndTerminalHandler(log_stream)
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
logging.getLogger().setLevel(logging.DEBUG)
logging.getLogger().addHandler(handler)
return log_stream
elif log_type == 'file':
if log_file:
logging.basicConfig(filename=log_file, level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s")
else:
print("Error: Log file path not provided for file logging.")
exit(1)
Using Logs
Throughout the code, logging statements are used to record important events and information:
logging.debug("Detailed information for debugging purposes")
logging.info("General information about program execution")
logging.warning("Warning messages")
logging.error("Error messages for serious problems")
logging.critical("Critical errors that may cause the program to terminate")
Debugging Techniques
1. Using Debug Logs
Enable debug logging to get detailed information about the application's execution:
python whisper2linux.py --log file --log-file debug.log
Review the log file for insights into the application's behavior.
2. Interactive Debugging
Use Python's built-in pdb
debugger for interactive debugging:
- Insert a breakpoint in the code:
import pdb; pdb.set_trace()
- Run the application normally, and it will pause at the breakpoint.
3. Performance Profiling
Use cProfile
to identify performance bottlenecks:
import cProfile
cProfile.run('main()')
4. Memory Profiling
Use libraries like memory_profiler
to track memory usage:
pip install memory_profiler
Then use it in your code:
from memory_profiler import profile
@profile
def memory_intensive_function():
# Function code here
5. Error Handling and Reporting
Implement comprehensive error handling to catch and log exceptions:
try:
# Some operation
except Exception as e:
logging.error(f"An error occurred: {str(e)}", exc_info=True)
6. Debugging API Interactions
For debugging API calls, use logging to record request and response details:
logging.debug(f"API Request: {url}, Data: {data}")
response = requests.post(url, json=data)
logging.debug(f"API Response: Status {response.status_code}, Content: {response.text}")
7. GUI Debugging (if applicable)
If implementing a GUI, consider adding debug overlays or a debug console for real-time information display.
8. Unit Testing
Implement unit tests to isolate and debug specific components:
import unittest
class TestWhisper2Linux(unittest.TestCase):
def test_transcribe_audio(self):
# Test code here
pass
if __name__ == '__main__':
unittest.main()
9. Logging Decorators
Use decorators to add logging to functions automatically:
def log_function_call(func):
def wrapper(*args, **kwargs):
logging.debug(f"Calling function: {func.__name__}")
result = func(*args, **kwargs)
logging.debug(f"Function {func.__name__} completed")
return result
return wrapper
@log_function_call
def some_function():
# Function code here
10. Environment-specific Debugging
Use environment variables to enable additional debugging features:
import os
if os.environ.get('WHISPER2LINUX_DEBUG'):
# Enable additional debug features
Best Practices for Debugging
- Reproducibility: Always try to create a reproducible test case for bugs.
- Isolation: Isolate the problem to the smallest possible code segment.
- Logging: Use appropriate log levels and include relevant context in log messages.
- Version Control: Use version control to track changes and revert if necessary.
- Documentation: Document any non-obvious bugs and their solutions for future reference.
Troubleshooting Common Issues
-
Audio Input Problems:
- Check microphone permissions and system audio settings.
- Verify the
MIC_DEVICE
setting in the configuration.
-
API Connection Issues:
- Check network connectivity and firewall settings.
- Verify API endpoint URLs and authentication credentials.
-
Performance Degradation:
- Review performance logs for bottlenecks.
- Check system resource usage (CPU, memory, disk I/O).
-
Command Recognition Errors:
- Analyze transcription accuracy in debug logs.
- Review and possibly adjust fuzzy matching thresholds.
By utilizing these logging and debugging techniques, you can effectively identify, isolate, and resolve issues in Whisper2Linux, ensuring its reliable operation and facilitating ongoing development and improvement.