Skip to content

Commit c8f9422

Browse files
authored
Merge pull request #3 from Naoray/v3
V3
2 parents a7093e0 + 5464862 commit c8f9422

39 files changed

+1303
-1193
lines changed

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
os: [ubuntu-latest]
3232
php: [8.4, 8.3]
3333
laravel: [11.*]
34-
stability: [prefer-lowest, prefer-stable]
34+
stability: [prefer-stable]
3535
include:
3636
- laravel: 11.*
3737
testbench: 9.*

README.md

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Automatically create GitHub issues from your Laravel exceptions & logs. Perfect
2121
- 🏷️ Support customizable labels
2222
- 🎯 Smart deduplication to prevent issue spam
2323
- ⚡️ Buffered logging for better performance
24+
- 📝 Customizable issue templates
2425

2526
## Showcase
2627

@@ -103,51 +104,46 @@ Log::stack(['daily', 'github'])->error('Something went wrong!');
103104

104105
## Advanced Configuration
105106

106-
Deduplication and buffering are enabled by default to enhance logging. Customize these features to suit your needs.
107+
### Customizing Templates
108+
109+
The package uses Markdown templates to format issues and comments. You can customize these templates by publishing them:
110+
111+
```bash
112+
php artisan vendor:publish --tag="github-monolog-views"
113+
```
114+
115+
This will copy the templates to `resources/views/vendor/github-monolog/` where you can modify them:
116+
117+
- `issue.md`: Template for new issues
118+
- `comment.md`: Template for comments on existing issues
119+
- `previous_exception.md`: Template for previous exceptions in the chain
120+
121+
Available template variables:
122+
- `{level}`: Log level (error, warning, etc.)
123+
- `{message}`: The error message or log content
124+
- `{simplified_stack_trace}`: A cleaned up stack trace
125+
- `{full_stack_trace}`: The complete stack trace
126+
- `{previous_exceptions}`: Details of any previous exceptions
127+
- `{context}`: Additional context data
128+
- `{extra}`: Extra log data
129+
- `{signature}`: Internal signature used for deduplication
107130

108131
### Deduplication
109132

110-
Group similar errors to avoid duplicate issues. By default, the package uses file-based storage. Customize the storage and time window to fit your application.
133+
Group similar errors to avoid duplicate issues. The package uses Laravel's cache system for deduplication storage.
111134

112135
```php
113136
'github' => [
114137
// ... basic config from above ...
115138
'deduplication' => [
116-
'store' => 'file', // Default store
117-
'time' => 60, // Time window in seconds
139+
'time' => 60, // Time window in seconds - how long to wait before creating a new issue
140+
'store' => null, // Uses your default cache store (from cache.default)
141+
'prefix' => 'dedup', // Prefix for cache keys
118142
],
119143
]
120144
```
121145

122-
#### Alternative Storage Options
123-
124-
Consider other storage options in these Laravel-specific scenarios:
125-
126-
- **Redis Store**: Use when:
127-
- Running async queue jobs (file storage won't work across processes)
128-
- Using Laravel Horizon for queue management
129-
- Running multiple application instances behind a load balancer
130-
131-
```php
132-
'deduplication' => [
133-
'store' => 'redis',
134-
'prefix' => 'github-monolog:',
135-
'connection' => 'default', // Uses your Laravel Redis connection
136-
],
137-
```
138-
139-
- **Database Store**: Use when:
140-
- Running queue jobs but Redis isn't available
141-
- Need to persist deduplication data across deployments
142-
- Want to query/debug deduplication history via database
143-
144-
```php
145-
'deduplication' => [
146-
'store' => 'database',
147-
'table' => 'github_monolog_deduplication',
148-
'connection' => null, // Uses your default database connection
149-
],
150-
```
146+
For cache store configuration, refer to the [Laravel Cache documentation](https://laravel.com/docs/cache).
151147

152148
### Buffering
153149

UPGRADE.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Upgrade Guide
2+
3+
## Upgrading from 2.x to 3.0
4+
5+
### Breaking Changes
6+
7+
Version 3.0 introduces several breaking changes in how deduplication storage is handled:
8+
9+
1. **Removed Custom Store Implementations**
10+
- FileStore, RedisStore, and DatabaseStore have been removed
11+
- All deduplication storage now uses Laravel's cache system
12+
13+
2. **Configuration Changes**
14+
- Store-specific configuration options have been removed
15+
- New simplified cache-based configuration
16+
17+
### Migration Steps
18+
19+
1. **Update Package**
20+
```bash
21+
composer require naoray/laravel-github-monolog:^3.0
22+
```
23+
24+
2. **Run Cleanup**
25+
- Keep your old configuration in place
26+
- Run the cleanup code in [Cleanup Code](#cleanup-code) to remove old storage artifacts
27+
- The cleanup code needs your old configuration to know what to clean up
28+
29+
3. **Update Configuration**
30+
- Migrate to new store-specific configuration
31+
- Add new cache-based configuration
32+
- Configure Laravel cache as needed
33+
34+
### Configuration Updates
35+
36+
#### Before (2.x)
37+
```php
38+
'deduplication' => [
39+
'store' => 'redis', // or 'file', 'database'
40+
'connection' => 'default', // Redis/Database connection
41+
'prefix' => 'github-monolog:', // Redis prefix
42+
'table' => 'github_monolog_deduplication', // Database table
43+
'time' => 60,
44+
],
45+
```
46+
47+
#### After (3.0)
48+
```php
49+
'deduplication' => [
50+
'store' => null, // (optional) Uses Laravel's default cache store
51+
'time' => 60, // Time window in seconds
52+
'prefix' => 'dedup', // Cache key prefix
53+
],
54+
```
55+
56+
### Cleanup Code
57+
58+
Before updating your configuration to the new format, you should clean up artifacts from the 2.x version. The cleanup code uses your existing configuration to find and remove old storage:
59+
60+
```php
61+
use Illuminate\Support\Facades\{Schema, Redis, File, DB};
62+
63+
// Get your current config
64+
$config = config('logging.channels.github.deduplication', []);
65+
$store = $config['store'] ?? 'file';
66+
67+
if ($store === 'database') {
68+
// Clean up database table using your configured connection and table name
69+
$connection = $config['connection'] ?? config('database.default');
70+
$table = $config['table'] ?? 'github_monolog_deduplication';
71+
72+
Schema::connection($connection)->dropIfExists($table);
73+
}
74+
75+
if ($store === 'redis') {
76+
// Clean up Redis entries using your configured connection and prefix
77+
$connection = $config['connection'] ?? 'default';
78+
$prefix = $config['prefix'] ?? 'github-monolog:';
79+
Redis::connection($connection)->del($prefix . 'dedup');
80+
}
81+
82+
if ($store === 'file') {
83+
// Clean up file storage using your configured path
84+
$path = $config['path'] ?? storage_path('logs/github-monolog-deduplication.log');
85+
if (File::exists($path)) {
86+
File::delete($path);
87+
}
88+
}
89+
```

composer.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@
2323
"illuminate/http": "^11.0",
2424
"illuminate/support": "^11.0",
2525
"illuminate/filesystem": "^11.0",
26+
"illuminate/cache": "^11.0",
2627
"monolog/monolog": "^3.6"
2728
},
2829
"require-dev": {
2930
"laravel/pint": "^1.14",
30-
"nunomaduro/collision": "^8.1.1||^7.10.0",
31+
"nunomaduro/collision": "^8.1.1",
3132
"larastan/larastan": "^2.9",
32-
"orchestra/testbench": "^9.0.0||^8.22.0",
33-
"pestphp/pest": "^2.35|^3.0",
34-
"pestphp/pest-plugin-arch": "^2.7||^3.0",
35-
"pestphp/pest-plugin-laravel": "^2.4||^3.0",
33+
"orchestra/testbench": "^9.0.0",
34+
"pestphp/pest": "^3.0",
35+
"pestphp/pest-plugin-arch": "^3.0",
36+
"pestphp/pest-plugin-laravel": "^3.0",
3637
"phpstan/extension-installer": "^1.3",
3738
"phpstan/phpstan-deprecation-rules": "^1.1",
3839
"phpstan/phpstan-phpunit": "^1.3"
@@ -62,6 +63,13 @@
6263
"phpstan/extension-installer": true
6364
}
6465
},
66+
"extra": {
67+
"laravel": {
68+
"providers": [
69+
"Naoray\\LaravelGithubMonolog\\GithubMonologServiceProvider"
70+
]
71+
}
72+
},
6573
"minimum-stability": "dev",
6674
"prefer-stable": true
6775
}

resources/views/comment.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# New Occurrence
2+
3+
**Log Level:** {level}
4+
5+
{message}
6+
7+
**Simplified Stack Trace:**
8+
```php
9+
{simplified_stack_trace}
10+
```
11+
12+
<details>
13+
<summary>Complete Stack Trace</summary>
14+
15+
```php
16+
{full_stack_trace}
17+
```
18+
</details>
19+
20+
<details>
21+
<summary>Previous Exceptions</summary>
22+
23+
{previous_exceptions}
24+
</details>
25+
26+
{context}
27+
28+
{extra}

resources/views/issue.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
**Log Level:** {level}
2+
3+
{message}
4+
5+
**Simplified Stack Trace:**
6+
```php
7+
{simplified_stack_trace}
8+
```
9+
10+
<details>
11+
<summary>Complete Stack Trace</summary>
12+
13+
```php
14+
{full_stack_trace}
15+
```
16+
</details>
17+
18+
<details>
19+
<summary>Previous Exceptions</summary>
20+
21+
{previous_exceptions}
22+
</details>
23+
24+
{context}
25+
26+
{extra}
27+
28+
<!-- Signature: {signature} -->

resources/views/previous_exception.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
### Previous Exception #{count}
2+
**Type:** {type}
3+
4+
**Simplified Stack Trace:**
5+
```php
6+
{simplified_stack_trace}
7+
```
8+
9+
<details>
10+
<summary>Complete Stack Trace</summary>
11+
12+
```php
13+
{full_stack_trace}
14+
```
15+
</details>

src/Deduplication/CacheManager.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace Naoray\LaravelGithubMonolog\Deduplication;
4+
5+
use Illuminate\Contracts\Cache\Repository;
6+
use Illuminate\Support\Carbon;
7+
use Illuminate\Support\Facades\Cache;
8+
9+
class CacheManager
10+
{
11+
private const KEY_PREFIX = 'github-monolog';
12+
13+
private const KEY_SEPARATOR = ':';
14+
15+
private readonly string $store;
16+
17+
private readonly Repository $cache;
18+
19+
public function __construct(
20+
?string $store = null,
21+
private readonly string $prefix = 'dedup',
22+
private readonly int $ttl = 60
23+
) {
24+
$this->store = $store ?? config('cache.default');
25+
$this->cache = Cache::store($this->store);
26+
}
27+
28+
public function has(string $signature): bool
29+
{
30+
return $this->cache->has($this->composeKey($signature));
31+
}
32+
33+
public function add(string $signature): void
34+
{
35+
$this->cache->put(
36+
$this->composeKey($signature),
37+
Carbon::now()->timestamp,
38+
$this->ttl
39+
);
40+
}
41+
42+
/**
43+
* Clear all entries for the current prefix.
44+
* Note: This is a best-effort operation and might not work with all cache stores.
45+
*/
46+
public function clear(): void
47+
{
48+
// For Redis/Memcached stores that support tag-like operations
49+
if (method_exists($this->cache->getStore(), 'flush')) {
50+
$this->cache->getStore()->flush();
51+
52+
return;
53+
}
54+
55+
// For other stores, we'll have to rely on TTL cleanup
56+
// You might want to implement a more specific cleanup strategy
57+
// based on your cache store if needed
58+
}
59+
60+
private function composeKey(string $signature): string
61+
{
62+
return implode(self::KEY_SEPARATOR, [
63+
self::KEY_PREFIX,
64+
$this->prefix,
65+
$signature,
66+
]);
67+
}
68+
}

0 commit comments

Comments
 (0)