Skip to content

Commit 855ed33

Browse files
committed
wip
1 parent f4f8c56 commit 855ed33

20 files changed

+287
-857
lines changed

README.md

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -107,47 +107,20 @@ Deduplication and buffering are enabled by default to enhance logging. Customize
107107

108108
### Deduplication
109109

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.
110+
Group similar errors to avoid duplicate issues. The package uses Laravel's cache system for deduplication storage.
111111

112112
```php
113113
'github' => [
114114
// ... basic config from above ...
115115
'deduplication' => [
116-
'store' => 'file', // Default store
117-
'time' => 60, // Time window in seconds
116+
'time' => 60, // Time window in seconds - how long to wait before creating a new issue
117+
'store' => null, // Uses your default cache store (from cache.default)
118+
'prefix' => 'dedup', // Prefix for cache keys
118119
],
119120
]
120121
```
121122

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-
```
123+
For cache store configuration, refer to the [Laravel Cache documentation](https://laravel.com/docs/cache).
151124

152125
### Buffering
153126

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 above 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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
"illuminate/http": "^11.0",
2424
"illuminate/support": "^11.0",
2525
"illuminate/filesystem": "^11.0",
26-
"monolog/monolog": "^3.6"
26+
"illuminate/cache": "^11.0",
27+
"monolog/monolog": "^3.6",
28+
"laravel/prompts": "^0.3.3"
2729
},
2830
"require-dev": {
2931
"laravel/pint": "^1.14",

src/Deduplication/CacheManager.php

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

src/Deduplication/DeduplicationHandler.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
use Monolog\Handler\HandlerInterface;
88
use Monolog\Level;
99
use Monolog\LogRecord;
10-
use Naoray\LaravelGithubMonolog\Deduplication\Stores\StoreInterface;
1110

1211
class DeduplicationHandler extends BufferHandler
1312
{
13+
private CacheManager $cache;
14+
1415
public function __construct(
1516
HandlerInterface $handler,
16-
protected StoreInterface $store,
1717
protected SignatureGeneratorInterface $signatureGenerator,
18+
string $store = 'default',
19+
string $prefix = 'github-monolog:dedup:',
20+
int $ttl = 60,
1821
int|string|Level $level = Level::Error,
1922
int $bufferLimit = 0,
2023
bool $bubble = true,
@@ -27,6 +30,8 @@ public function __construct(
2730
bubble: $bubble,
2831
flushOnOverflow: $flushOnOverflow,
2932
);
33+
34+
$this->cache = new CacheManager($store, $prefix, $ttl);
3035
}
3136

3237
public function flush(): void
@@ -42,17 +47,17 @@ public function flush(): void
4247
// Create new record with signature in extra data
4348
$record = $record->with(extra: ['github_issue_signature' => $signature] + $record->extra);
4449

45-
// If the record is a duplicate, we don't want to add it to the store
46-
if ($this->store->isDuplicate($record, $signature)) {
50+
// If the record is a duplicate, we don't want to process it
51+
if ($this->cache->has($signature)) {
4752
return null;
4853
}
4954

50-
$this->store->add($record, $signature);
55+
$this->cache->add($signature);
5156

5257
return $record;
5358
})
5459
->filter()
55-
->pipe(fn (Collection $records) => $this->handler->handleBatch($records->toArray()));
60+
->pipe(fn(Collection $records) => $this->handler->handleBatch($records->toArray()));
5661

5762
$this->clear();
5863
}

src/Deduplication/Stores/AbstractStore.php

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/Deduplication/Stores/DatabaseStore.php

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)