Python Error Tracker
Imagine you're building a critical application, and unexpected errors can cause major disruptions. You need a robust system to log these errors effectively, so you can diagnose and fix them quickly. This challenge asks you to create a simple yet effective error tracking mechanism in Python.
Problem Description
Your task is to implement a Python class, ErrorTracker, that can record and report different types of errors encountered within an application. The tracker should allow users to log errors, specify their severity, and store them for later retrieval. The goal is to provide a centralized way to manage errors, making debugging and maintenance significantly easier.
Key Requirements:
- Error Logging: The
ErrorTrackerclass must have a method to log errors. This method should accept the error message, the type of error (e.g., "ValueError", "TypeError", "CustomError"), and an optional severity level (e.g., "INFO", "WARNING", "ERROR", "CRITICAL"). - Error Storage: Logged errors should be stored internally by the
ErrorTrackerinstance. A list or dictionary would be suitable for this. - Error Retrieval: Implement methods to retrieve errors based on different criteria:
- Get all logged errors.
- Get errors of a specific type.
- Get errors of a specific severity level.
- Error Counting: Provide a method to get the total number of errors logged.
- Error Reporting (Basic): Implement a method to generate a summary report of all logged errors, grouped by severity and type, along with their counts.
Expected Behavior:
- When an error is logged, it should be added to the tracker's internal storage.
- Retrieval methods should return the correct subset of logged errors based on the provided criteria.
- The error count should accurately reflect the total number of logged errors.
- The reporting method should present a clear and organized summary of the error landscape.
Edge Cases to Consider:
- What happens if no errors are logged? Retrieval and reporting methods should handle this gracefully.
- What if a logged error has an unknown severity level? The tracker should still store it, and reporting might group it separately or default to a "UNKNOWN" category.
- Ensure that the
ErrorTrackerinstance itself doesn't crash when encountering invalid input for error logging (e.g., non-string error messages or invalid severity).
Examples
Example 1:
tracker = ErrorTracker()
tracker.log_error("File not found", "FileNotFoundError", "ERROR")
tracker.log_error("Invalid input format", "ValueError", "WARNING")
tracker.log_error("Database connection failed", "CustomError", "CRITICAL")
print(f"Total errors: {tracker.get_total_errors()}")
errors = tracker.get_all_errors()
print("All errors:")
for error in errors:
print(f"- {error}")
Output:
Total errors: 3
All errors:
- {'message': 'File not found', 'type': 'FileNotFoundError', 'severity': 'ERROR'}
- {'message': 'Invalid input format', 'type': 'ValueError', 'severity': 'WARNING'}
- {'message': 'Database connection failed', 'type': 'CustomError', 'severity': 'CRITICAL'}
Explanation:
Three errors are logged with different messages, types, and severities. The total error count is correctly reported as 3, and get_all_errors returns a list of dictionaries, each representing a logged error.
Example 2:
tracker = ErrorTracker()
tracker.log_error("Division by zero", "ArithmeticError", "ERROR")
tracker.log_error("User not authenticated", "AuthenticationError", "WARNING")
tracker.log_error("Division by zero", "ArithmeticError", "ERROR") # Duplicate error
errors_by_type = tracker.get_errors_by_type("ArithmeticError")
print("Arithmetic Errors:")
for error in errors_by_type:
print(f"- {error['message']}")
errors_by_severity = tracker.get_errors_by_severity("ERROR")
print("\nErrors with ERROR severity:")
for error in errors_by_severity:
print(f"- {error['message']} ({error['type']})")
Output:
Arithmetic Errors:
- Division by zero
- Division by zero
Errors with ERROR severity:
- Division by zero (ArithmeticError)
- Division by zero (ArithmeticError)
Explanation:
Errors are logged, including a duplicate "Division by zero" error. get_errors_by_type correctly filters and returns all logged arithmetic errors. get_errors_by_severity returns all errors marked as "ERROR".
Example 3: (Reporting and edge case)
tracker = ErrorTracker()
tracker.log_error("User ID missing", "ValueError", "WARNING")
tracker.log_error("Connection timeout", "NetworkError", "ERROR")
tracker.log_error("Unexpected response", "NetworkError", "ERROR")
tracker.log_error("Empty configuration", "ConfigError", "CRITICAL")
tracker.log_error("Invalid data type", "TypeError", "INFO")
tracker.log_error("Unknown issue", "UnknownError", "UNKNOWN_SEVERITY") # Invalid severity
report = tracker.generate_report()
print("Error Report:")
print(report)
empty_tracker = ErrorTracker()
print(f"\nTotal errors in empty tracker: {empty_tracker.get_total_errors()}")
print("Report for empty tracker:")
print(empty_tracker.generate_report())
Output:
Error Report:
Severity Counts:
INFO: 1
WARNING: 1
ERROR: 2
CRITICAL: 1
UNKNOWN_SEVERITY: 1
Error Type Counts:
ValueError: 1
NetworkError: 2
ConfigError: 1
TypeError: 1
UnknownError: 1
Total errors: 6
Total errors in empty tracker: 0
Report for empty tracker:
Severity Counts:
(No errors logged)
Error Type Counts:
(No errors logged)
Total errors: 0
Explanation:
This example demonstrates logging with an intentionally invalid severity level, which is still stored. The generate_report method provides a structured summary of errors by severity and type. It also shows how an empty tracker handles reporting gracefully.
Constraints
- The
ErrorTrackerclass must be implemented in a single Python file. - The error message, type, and severity should be stored as strings.
- The maximum number of errors that can be logged by a single
ErrorTrackerinstance is not explicitly limited by this challenge, but consider efficient storage for a large number of errors. - The
generate_reportmethod should return a single string. - The code should be compatible with Python 3.6+.
Notes
- Consider using a dictionary to store errors internally, perhaps keyed by a unique ID if you want to implement features like updating or deleting specific errors later (though this is not required for this challenge).
- For the
generate_reportmethod, think about how to efficiently count occurrences of each severity and type. - You can define default severity levels if you wish, but ensure your code handles cases where an unknown severity is provided.
- Focus on clear, readable, and well-commented code. Good error tracking is about clarity!