Skip to main content

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:

  1. Insert a breakpoint in the code:
    import pdb; pdb.set_trace()
  2. 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

  1. Reproducibility: Always try to create a reproducible test case for bugs.
  2. Isolation: Isolate the problem to the smallest possible code segment.
  3. Logging: Use appropriate log levels and include relevant context in log messages.
  4. Version Control: Use version control to track changes and revert if necessary.
  5. Documentation: Document any non-obvious bugs and their solutions for future reference.

Troubleshooting Common Issues

  1. Audio Input Problems:

    • Check microphone permissions and system audio settings.
    • Verify the MIC_DEVICE setting in the configuration.
  2. API Connection Issues:

    • Check network connectivity and firewall settings.
    • Verify API endpoint URLs and authentication credentials.
  3. Performance Degradation:

    • Review performance logs for bottlenecks.
    • Check system resource usage (CPU, memory, disk I/O).
  4. 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.