Skip to content

Commit 559a6a5

Browse files
Merge pull request #10 from TheDragonCode/1.x
Added `withLogger` macro for Request
2 parents 4e328ff + 36e820a commit 559a6a5

File tree

8 files changed

+165
-3
lines changed

8 files changed

+165
-3
lines changed

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ Http::get()->toData(...); // will be method not found exception
6868

6969
### Available Methods
7070

71+
#### Request
72+
73+
- [withLogger](#withlogger)
7174

7275
#### Response
7376

@@ -76,6 +79,43 @@ Http::get()->toData(...); // will be method not found exception
7679

7780
### Method Listing
7881

82+
#### withLogger()
83+
84+
Adds the ability to log HTTP requests and responses.
85+
86+
```php
87+
use Illuminate\Support\Facades\Http;
88+
89+
Http::withLogger('some_channel')->get();
90+
```
91+
92+
This method will log HTTP requests and responses.
93+
94+
It is also possible to use your own handler, message formatting and path to the log file.
95+
To do this, you need to specify the desired channel name from the log file and define the necessary parameters in it.
96+
97+
For example:
98+
99+
```php
100+
// config/logging.php
101+
return [
102+
// ...
103+
104+
'channels' => [
105+
'some' => [
106+
'driver' => 'single',
107+
'level' => env('LOG_LEVEL', 'debug'),
108+
'path' => storage_path('logs/some.log'),
109+
'handler' => \App\Logging\SomeHandlerStack::class,
110+
'formatter' => \App\Logging\MessageFormatter::class,
111+
],
112+
],
113+
];
114+
115+
// Usage
116+
return Http::withLogger('some')->...
117+
```
118+
79119
#### toData()
80120

81121
The class instance will be returned.

config/http.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
declare(strict_types=1);
44

5+
use DragonCode\LaravelHttpMacros\Macros\Requests\WithLoggerMacro;
56
use DragonCode\LaravelHttpMacros\Macros\Responses\ToDataCollectionMacro;
67
use DragonCode\LaravelHttpMacros\Macros\Responses\ToDataMacro;
78

89
return [
910
'macros' => [
1011
'request' => [
12+
WithLoggerMacro::class,
13+
1114
// CustomMacro::class,
1215
// 'toFoo' => CustomMacro::class,
1316
],

ide.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "https://laravel-ide.com/schema/laravel-ide-v2.json",
3+
"completions": [
4+
{
5+
"complete": "configKey",
6+
"options": {
7+
"prefix": "logging.channels"
8+
},
9+
"condition": [
10+
{
11+
"methodNames": [
12+
"withLogger"
13+
],
14+
"classFqn": [
15+
"\\Illuminate\\Http\\Client\\Factory",
16+
"\\Illuminate\\Http\\Client\\PendingRequest",
17+
"\\Illuminate\\Http\\Client\\Request",
18+
"\\Illuminate\\Support\\Facades\\Http"
19+
],
20+
"parameters": [
21+
1
22+
]
23+
}
24+
]
25+
}
26+
]
27+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelHttpMacros\Macros\Requests;
6+
7+
use Closure;
8+
use DragonCode\LaravelHttpMacros\Macros\Macro;
9+
use GuzzleHttp\HandlerStack;
10+
use GuzzleHttp\MessageFormatter;
11+
use GuzzleHttp\Middleware;
12+
use Illuminate\Http\Client\PendingRequest;
13+
use Monolog\Handler\StreamHandler;
14+
use Monolog\Logger;
15+
16+
use function call_user_func;
17+
use function config;
18+
use function storage_path;
19+
20+
/**
21+
* Adds the ability to log HTTP requests and responses.
22+
*/
23+
class WithLoggerMacro extends Macro
24+
{
25+
public static function callback(): Closure
26+
{
27+
return function (string $channel): PendingRequest {
28+
$config = config('logging.channels.' . $channel);
29+
30+
$handler = call_user_func([$config['handler'] ?? HandlerStack::class, 'create']);
31+
$formatter = $config['formatter'] ?? MessageFormatter::class;
32+
33+
$path = $config['path'] ?? storage_path('logs/laravel.log');
34+
35+
$logger = (new Logger($channel))->pushHandler(
36+
new StreamHandler($path)
37+
);
38+
39+
$handler->push(
40+
Middleware::log($logger, new $formatter())
41+
);
42+
43+
return $this->setHandler($handler);
44+
};
45+
}
46+
47+
public static function name(): string
48+
{
49+
return 'withLogger';
50+
}
51+
}

src/ServiceProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use DragonCode\LaravelHttpMacros\Commands\GenerateHelperCommand;
88
use DragonCode\LaravelHttpMacros\Macros\Macro;
9-
use Illuminate\Http\Client\Request;
9+
use Illuminate\Http\Client\PendingRequest;
1010
use Illuminate\Http\Client\Response;
1111
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
1212

@@ -42,7 +42,7 @@ protected function bootCommands(): void
4242
protected function bootRequestMacros(): void
4343
{
4444
foreach ($this->requestMacros() as $name => $macro) {
45-
Request::macro($this->resolveName($name, $macro), $macro::callback());
45+
PendingRequest::macro($this->resolveName($name, $macro), $macro::callback());
4646
}
4747
}
4848

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Fixtures\Logging;
6+
7+
use GuzzleHttp\MessageFormatterInterface;
8+
use Psr\Http\Message\RequestInterface;
9+
use Psr\Http\Message\ResponseInterface;
10+
use Throwable;
11+
12+
class MessageFormater implements MessageFormatterInterface
13+
{
14+
public function __construct(
15+
protected string $template = 'REQUEST: {request} RESPONSE: {response}'
16+
) {}
17+
18+
public function format(
19+
RequestInterface $request,
20+
?ResponseInterface $response = null,
21+
?Throwable $error = null
22+
): string {
23+
return str_replace(['{request}', '{response}'], [
24+
$request->getUri(),
25+
$response->getBody()->getContents(),
26+
], $this->template);
27+
}
28+
}

tests/Helpers/fake.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
declare(strict_types=1);
44

55
use Illuminate\Http\Client\Factory;
6+
use Illuminate\Support\Facades\Http;
67

78
function fakeRequest(): Factory
89
{
9-
return (new Factory())->fake([
10+
return Http::fake([
1011
'simple' => [
1112
'id' => 1,
1213
'title' => 'Qwerty 1',

tests/TestCase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Config\Repository;
99
use Orchestra\Testbench\TestCase as BaseTestCase;
1010
use Spatie\LaravelData\LaravelDataServiceProvider;
11+
use Tests\Fixtures\Logging\MessageFormater;
1112

1213
abstract class TestCase extends BaseTestCase
1314
{
@@ -28,6 +29,17 @@ protected function defineEnvironment($app): void
2829

2930
'toFoo' => ToDataMacro::class,
3031
]);
32+
33+
$config->set('logging.channels.foo', [
34+
'driver' => 'single',
35+
'path' => storage_path('logs/foo.log'),
36+
]);
37+
38+
$config->set('logging.channels.bar', [
39+
'driver' => 'single',
40+
'path' => storage_path('logs/bar.log'),
41+
'formatter' => MessageFormater::class,
42+
]);
3143
});
3244
}
3345
}

0 commit comments

Comments
 (0)