# Enhanced Error Logging System

This document explains the enhanced error logging system that captures the actual line number where errors occur, rather than where the logging method is called.

## Problem Solved

Previously, when you logged an exception like this:
```php
try {
    // Some code that throws an exception at line 50
    $result = riskyOperation();
} catch (\Exception $e) {
    Log::error('Operation failed: ' . $e->getMessage()); // This was logged as line 53
}
```

The log would show line 53 (where `Log::error` was called) instead of line 50 (where the actual error occurred).

## Solution

The enhanced logging system now:
1. **Automatically detects exception logging** and extracts the original error location
2. **Stores both locations**: where the error occurred AND where it was logged
3. **Provides helper methods** for easier exception logging
4. **Maintains backward compatibility** with existing code

## How It Works

### Automatic Detection
The system automatically detects when you're logging an exception by:
- Looking for exception objects in the log context
- Analyzing log messages for exception patterns
- Searching the call stack for exception objects

### Enhanced Context Storage
For exception logs, the system now stores:
```json
{
  "source": {
    "class": "ExampleClass",
    "function": "exampleMethod", 
    "file": "/path/to/actual/error/file.php",
    "line": 50,
    "exception_class": "InvalidArgumentException",
    "is_exception": true,
    "log_location": {
      "class": "ExampleClass",
      "function": "handleError",
      "file": "/path/to/logging/file.php", 
      "line": 53
    }
  }
}
```

## Usage

### Method 1: Use Helper Methods (Recommended)
```php
use App\Helpers\LogHelper;

try {
    $result = riskyOperation();
} catch (\Exception $e) {
    // This will capture the actual error line automatically
    LogHelper::logError($e, 'Operation failed');
    
    // Or with additional context
    LogHelper::logError($e, 'Operation failed', [
        'user_id' => $userId,
        'operation' => 'riskyOperation'
    ]);
}
```

### Method 2: Use Standard Laravel Logging (Still Works)
```php
try {
    $result = riskyOperation();
} catch (\Exception $e) {
    // The system will automatically detect this is an exception
    Log::error('Operation failed: ' . $e->getMessage());
}
```

### Method 3: Explicit Exception Context
```php
try {
    $result = riskyOperation();
} catch (\Exception $e) {
    // Pass the exception in context for guaranteed detection
    Log::error('Operation failed', ['exception' => $e]);
}
```

## Retrieving Enhanced Logs

### Get Logs with Enhanced Information
```php
use App\Helpers\LogHelper;

// Get all error logs with enhanced source info
$logs = LogHelper::getLogsWithEnhancedSource('error', 50);

foreach ($logs as $log) {
    echo "Message: " . $log->message . "\n";
    echo "Source: " . $log->source_info . "\n";
    
    if ($log->is_exception) {
        echo "This was an exception log\n";
        echo "Actual error: " . $log->exception_details['actual_error'] . "\n";
        echo "Logged from: " . $log->exception_details['logged_from'] . "\n";
    }
}
```

### Get Only Exception Logs
```php
// Get only logs that contain exception information
$exceptionLogs = LogHelper::getLogsWithEnhancedSource('error', 50, null, true);
```

### Search Logs
```php
// Search for specific errors
$searchResults = LogHelper::getLogsWithEnhancedSource('error', 100, 'database connection');
```

## Helper Methods Reference

### LogHelper::logError()
```php
LogHelper::logError(\Throwable $exception, string $message = null, array $additionalContext = [])
```
Logs an exception with error level and proper context.

### LogHelper::logException()
```php
LogHelper::logException(\Throwable $exception, string $message = null, array $additionalContext = [], string $level = 'error')
```
Logs an exception with specified level and proper context.

### LogHelper::getLogsWithEnhancedSource()
```php
LogHelper::getLogsWithEnhancedSource(?string $level = null, int $limit = 100, ?string $search = null, bool $exceptionsOnly = false)
```
Retrieves logs with enhanced source information including exception details.

## Testing

Test the enhanced logging system using the provided test routes:

1. **Generate test logs**: Visit `/test-logging`
2. **View results**: Visit `/view-test-logs`

These routes demonstrate:
- Regular logging behavior
- Old-style exception logging
- New helper method logging
- Nested function exception handling

## Migration Guide

### For New Code
Use the helper methods for all exception logging:
```php
// Instead of this:
Log::error('Error: ' . $e->getMessage());

// Use this:
LogHelper::logError($e, 'Error occurred');
```

### For Existing Code
No changes required! The system automatically detects and enhances existing exception logs.

### Optional Improvements
For better results, you can gradually update existing code to use the helper methods or pass exceptions in context:
```php
// Current code (still works):
Log::error('Database error: ' . $e->getMessage());

// Enhanced version:
LogHelper::logError($e, 'Database error occurred');

// Or with context:
Log::error('Database error', ['exception' => $e]);
```

## Benefits

1. **Accurate Error Location**: See exactly where errors occur, not where they're logged
2. **Better Debugging**: Faster identification of problematic code
3. **Backward Compatible**: Existing code continues to work
4. **Enhanced Context**: Both error location and logging location are preserved
5. **Easy Querying**: Filter and search exception logs specifically
6. **Detailed Information**: Exception class, stack traces, and custom context

## Database Schema

The enhanced logging uses the existing `logs` table structure. All additional information is stored in the JSON `context` column, so no database migrations are required.

## Performance Considerations

The enhanced logging adds minimal overhead:
- Exception detection uses efficient pattern matching
- Stack trace analysis only occurs for detected exceptions
- Database schema remains unchanged
- Existing log queries continue to work normally

## Troubleshooting

### Exception Not Detected
If an exception isn't being detected automatically:
1. Use `LogHelper::logError($e)` instead of `Log::error()`
2. Pass the exception in context: `Log::error('message', ['exception' => $e])`

### Missing Source Information
If source information is missing:
1. Ensure the exception object is available when logging
2. Check that the logging channel is set to use the database logger
3. Verify the `context` column in your logs table can store JSON data

### Performance Issues
If you experience performance issues:
1. The system only processes exception-related logs
2. Consider limiting log retention periods
3. Add database indexes on frequently queried log fields
