Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Satini_pvduc
/
daito-utils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Authored by
RESAZIP-PC\resaz
2026-02-23 23:26:40 +0700
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Commit
9fe3ba35981b840abdc55f1d3798bc27c7f3441b
9fe3ba35
1 parent
3aef053c
add daitoexceptionnotifier
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
181 additions
and
1 deletions
README.md
composer.json
src/DaitoExceptionNotifier.php
src/DaitoExceptionNotifier/DaitoExceptionNotifierManager.php
src/DaitoExceptionNotifier/Providers/DaitoExceptionNotifierProvider.php
src/DaitoExceptionNotifier/config/daito-exception-notifier.php
README.md
View file @
9fe3ba3
...
...
@@ -257,6 +257,93 @@ DAITO_GOOGLE_CHAT_VERIFY_SSL=false
Use this only for temporary debugging on local environment. Never disable SSL verification on production.
## DaitoExceptionNotifier (separate reusable module)
### 1) Publish config
```
bash
php artisan vendor:publish --tag
=
daito-exception-notifier-config
```
This creates
`config/daito-exception-notifier.php`
.
### 2) Minimal `.env` setup
```
dotenv
DAITO_EXCEPTION_NOTIFIER_ENABLED=true
DAITO_EXCEPTION_NOTIFIER_SEND_MODE=queue
DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_ENABLED=true
DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_TTL_SECONDS=30
DAITO_EXCEPTION_NOTIFIER_TRACE_MODE=smart
DAITO_EXCEPTION_NOTIFIER_TRACE_MAX_LINES=8
DAITO_EXCEPTION_NOTIFIER_TRACE_SKIP_VENDOR=true
DAITO_EXCEPTION_NOTIFIER_TRACE_INCLUDE_FIRST_APP_FRAME=true
```
### 3) Auto notify on exception (HTTP + CLI)
Use Laravel exception handler to automatically send exception cardV2:
```
php
<?php
namespace
App\Exceptions
;
use
Daito\Lib\DaitoExceptionNotifier
;
use
Illuminate\Foundation\Exceptions\Handler
as
ExceptionHandler
;
use
Throwable
;
class
Handler
extends
ExceptionHandler
{
public
function
register
()
{
$this
->
reportable
(
function
(
Throwable
$throwable
)
{
DaitoExceptionNotifier
::
notify
(
$throwable
);
});
}
}
```
`DaitoExceptionNotifier::notify()`
supports both route/controller errors and CLI command errors because Laravel routes both through the same exception handler.
If you want explicit mode:
```
php
DaitoExceptionNotifier::queue($throwable); // queue
DaitoExceptionNotifier::send($throwable); // sync immediate
```
Exception cardV2 includes:
-
`time`
-
`action`
-
`file`
-
`line`
-
`message`
-
compact
`trace`
(top useful frames only, configurable)
-
`first_app_frame`
(when available)
Trace filter strategy (
`DAITO_EXCEPTION_NOTIFIER_TRACE_MODE`
):
-
`smart`
(recommended): prefer app frames, then non-vendor frames, then fallback
-
`app_only`
: only frames that belong to
`app/`
or class prefix
`App\`
- `
no_vendor
`: remove `
vendor
` frames
- `
class_prefix_only
`: only frames by configured class prefixes (`
trace_class_prefixes
`)
### 4) Built-in loop guard (recommended default)
To avoid recursive notify loops when Google Chat send itself throws exceptions, this module has a built-in circuit-breaker:
- re-entrant guard in the same process/request
- short TTL dedupe by exception fingerprint (file+line+message+action)
- optional cache-based dedupe across workers/processes
Main config keys:
- `
loop_guard_enabled
`
- `
loop_guard_ttl_seconds
`
- `
loop_guard_use_cache
`
- `
loop_guard_cache_prefix
`
- `
loop_guard_skip_if_notifier_in_trace
`
## QueryLog (Laravel shared package)
> **Provider registration note**
...
...
composer.json
View file @
9fe3ba3
...
...
@@ -21,7 +21,8 @@
"laravel"
:
{
"providers"
:
[
"Daito
\\
Lib
\\
DaitoQueryLog
\\
Providers
\\
DaitoQueryLogProvider"
,
"Daito
\\
Lib
\\
DaitoGoogleChat
\\
Providers
\\
DaitoGoogleChatProvider"
"Daito
\\
Lib
\\
DaitoGoogleChat
\\
Providers
\\
DaitoGoogleChatProvider"
,
"Daito
\\
Lib
\\
DaitoExceptionNotifier
\\
Providers
\\
DaitoExceptionNotifierProvider"
]
}
}
...
...
src/DaitoExceptionNotifier.php
0 → 100644
View file @
9fe3ba3
<?php
namespace
Daito\Lib
;
use
Daito\Lib\DaitoExceptionNotifier\DaitoExceptionNotifierManager
;
use
RuntimeException
;
use
Throwable
;
class
DaitoExceptionNotifier
{
public
static
function
send
(
Throwable
$throwable
,
array
$arrContext
=
array
(),
$webhookUrl
=
null
)
:
array
{
return
self
::
manager
()
->
send
(
$throwable
,
$arrContext
,
$webhookUrl
);
}
public
static
function
queue
(
Throwable
$throwable
,
array
$arrContext
=
array
(),
$webhookUrl
=
null
)
:
void
{
self
::
manager
()
->
queue
(
$throwable
,
$arrContext
,
$webhookUrl
);
}
public
static
function
notify
(
Throwable
$throwable
,
array
$arrContext
=
array
(),
$webhookUrl
=
null
)
{
return
self
::
manager
()
->
notify
(
$throwable
,
$arrContext
,
$webhookUrl
);
}
private
static
function
manager
()
:
DaitoExceptionNotifierManager
{
if
(
!
function_exists
(
'app'
))
{
throw
new
RuntimeException
(
'Laravel app container is required for DaitoExceptionNotifier.'
);
}
$manager
=
app
(
DaitoExceptionNotifierManager
::
class
);
if
(
!
$manager
instanceof
DaitoExceptionNotifierManager
)
{
throw
new
RuntimeException
(
'Can not resolve DaitoExceptionNotifierManager from container.'
);
}
return
$manager
;
}
}
src/DaitoExceptionNotifier/DaitoExceptionNotifierManager.php
0 → 100644
View file @
9fe3ba3
This diff is collapsed.
Click to expand it.
src/DaitoExceptionNotifier/Providers/DaitoExceptionNotifierProvider.php
0 → 100644
View file @
9fe3ba3
<?php
namespace
Daito\Lib\DaitoExceptionNotifier\Providers
;
use
Daito\Lib\DaitoExceptionNotifier\DaitoExceptionNotifierManager
;
use
Daito\Lib\DaitoGoogleChat\DaitoGoogleChatManager
;
use
Illuminate\Support\ServiceProvider
;
class
DaitoExceptionNotifierProvider
extends
ServiceProvider
{
public
function
register
()
:
void
{
$this
->
mergeConfigFrom
(
__DIR__
.
'/../config/daito-exception-notifier.php'
,
'daito-exception-notifier'
);
$this
->
app
->
singleton
(
DaitoExceptionNotifierManager
::
class
,
function
(
$app
)
{
return
new
DaitoExceptionNotifierManager
(
$app
->
make
(
DaitoGoogleChatManager
::
class
)
);
});
}
public
function
boot
()
:
void
{
$this
->
publishes
(
array
(
__DIR__
.
'/../config/daito-exception-notifier.php'
=>
config_path
(
'daito-exception-notifier.php'
),
),
'daito-exception-notifier-config'
);
}
}
src/DaitoExceptionNotifier/config/daito-exception-notifier.php
0 → 100644
View file @
9fe3ba3
<?php
return
array
(
'enabled'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_ENABLED'
,
true
),
'send_mode'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_SEND_MODE'
,
'queue'
),
// queue|sync
'card_title'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_CARD_TITLE'
,
'Exception Alert'
),
'loop_guard_enabled'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_ENABLED'
,
true
),
'loop_guard_ttl_seconds'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_TTL_SECONDS'
,
30
),
'loop_guard_use_cache'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_USE_CACHE'
,
true
),
'loop_guard_cache_prefix'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_CACHE_PREFIX'
,
'daito-exception-notifier:loop'
),
'loop_guard_skip_if_notifier_in_trace'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_LOOP_GUARD_SKIP_NOTIFIER_TRACE'
,
true
),
'message_max_length'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_MESSAGE_MAX_LENGTH'
,
1000
),
'trace_mode'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_TRACE_MODE'
,
'smart'
),
// smart|app_only|no_vendor|class_prefix_only
'trace_class_prefixes'
=>
array
(
'App\\'
),
'trace_include_first_app_frame'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_TRACE_INCLUDE_FIRST_APP_FRAME'
,
true
),
'trace_max_lines'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_TRACE_MAX_LINES'
,
8
),
'trace_max_length'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_TRACE_MAX_LENGTH'
,
2500
),
'trace_skip_vendor'
=>
env
(
'DAITO_EXCEPTION_NOTIFIER_TRACE_SKIP_VENDOR'
,
true
),
);
Please
register
or
sign in
to post a comment