Skip to content

Support parameters #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 17, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.php_cs
.php_cs.cache
.phpunit.result.cache
.phpunit.cache
build
composer.lock
coverage
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ This package works as follows:
- `team_id`: The team id associated with the request (if available)
- `method`: The HTTP method (`GET/POST/...`)
- `route`: The route name (if available) or the route URI (eg `/posts/{post}`)
- `parameters`: The route parameters passed (if enabled else `null`)
- `status`: The HTTP status (eg `202`)
- `ip`: The request ip
- `date`: The date of the request as datetime (can be aggregated)
Expand Down
10 changes: 10 additions & 0 deletions config/route-statistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
*/
'enabled' => env('ROUTE_STATISTICS_ENABLED', true),

/*
|--------------------------------------------------------------------------
| Store parameters
|--------------------------------------------------------------------------
|
| If this setting is set to true the route parameters will also be logged.
|
*/
'store_route_parameters' => env('ROUTE_STATISTICS_STORE_ROUTE_PARAMETERS', false),

/*
|--------------------------------------------------------------------------
| Aggregation
Expand Down
1 change: 1 addition & 0 deletions database/factories/RouteStatisticFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public function definition()
'method' => $this->faker->randomElement(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),
'route' => $this->faker->domainWord().'.'.$this->faker->randomElement(['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']),
'status' => $this->faker->randomElement([200, 201, 202, 204, 300, 301, 302, 303, 304, 400, 401, 402, 403, 404, 405, 406, 422, 429, 500, 501, 502, 503, 504]),
'parameters' => $this->faker->json(),
'ip' => $this->faker->ipv4(),
'date' => $this->faker->dateTime(),
'counter' => $this->faker->randomNumber(4),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up()
{
Schema::table('route_statistics', function (Blueprint $table) {
$table->json('parameters')->after('route')->nullable();
});
}

public function down()
{
Schema::table('route_statistics', function (Blueprint $table) {
$table->dropColumn('parameters');
});
}
};
30 changes: 25 additions & 5 deletions src/Commands/LaravelRouteStatisticsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Bilfeldt\LaravelRouteStatistics\Commands;

use Bilfeldt\LaravelRouteStatistics\Models\RouteStatistic;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -40,11 +41,16 @@ public function handle()
$this->applyGrouping($query);
$this->applySorting($query);

$results = $query->limit($this->option('limit'))->get();
$fields = $this->getFields();

$results = $query
->limit($this->option('limit'))
->get()
->map(fn (RouteStatistic $model): array => $this->toTableRow($model, $fields));

$this->table(
$this->getFields(),
$results->toArray()
$fields,
$results
);

return Command::SUCCESS;
Expand Down Expand Up @@ -111,16 +117,30 @@ protected function getFields(): array
return array_merge($this->option('group'), ['last_used', 'counter']);
}

return [
return array_filter([
'id',
'user_id',
'team_id',
'method',
'route',
'status',
config('route-statistics.store_route_parameters') === true ? 'parameters' : null,
'ip',
'date',
'counter',
];
]);
}

/**
* @param RouteStatistic $model
* @param $fields array<string>
* @return array<string>
*/
protected function toTableRow(RouteStatistic $model, array $fields): array
{
return array_map(
fn (mixed $item): mixed => is_array($item) ? json_encode($item) : $item,
$model->only($fields)
);
}
}
1 change: 1 addition & 0 deletions src/LaravelRouteStatisticsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private function publishMigrations()
{
$this->publishes([
__DIR__.'/../database/migrations/create_route_statistics_table.php.stub' => database_path('migrations/'.date('Y_m_d_His', time()).'_create_route_statistics_table.php'),
__DIR__.'/../database/migrations/add_parameters_to_route_statistics_table.php.stub' => database_path('migrations/'.date('Y_m_d_His', time()).'_add_parameters_to_route_statistics_table.php'),
// you can add any number of migrations here
], 'migrations');
}
Expand Down
2 changes: 2 additions & 0 deletions src/Models/RouteStatistic.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class RouteStatistic extends Model implements RequestLoggerInterface

protected $casts = [
'date' => 'datetime',
'parameters' => 'array',
];

//======================================================================
Expand Down Expand Up @@ -85,6 +86,7 @@ public function getLogAttributes(Request $request, $response, ?int $time = null,
'team_id' => $this->getRequestTeam($request)?->getKey(),
'method' => $request->getMethod(),
'route' => $request->route()?->getName() ?? $request->route()?->uri(),
'parameters' => config('route-statistics.store_route_parameters') ? $request->route()->originalParameters() : null,
'status' => $response->getStatusCode(),
'ip' => $request->ip(),
'date' => $this->getDate(),
Expand Down
14 changes: 12 additions & 2 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ public function getEnvironmentSetUp($app)
'prefix' => '',
]);

$migration = include __DIR__.'/../database/migrations/create_route_statistics_table.php.stub';
$migration->up();
$this->runMigrations([
'create_route_statistics_table',
'add_parameters_to_route_statistics_table',
]);
}

private function runMigrations(array $fileNames): void
{
foreach ($fileNames as $fileName) {
$class = require __DIR__.'/../database/migrations/'.$fileName.'.php.stub';
$class->up();
}
}
}
48 changes: 48 additions & 0 deletions tests/Unit/RouteStatisticModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,52 @@ public function test_get_log_attributes(): void
{
$this->markTestIncomplete('Mock the request and response to ensture the correct attributes are returned');
}

public function test_logs_parameters_if_config_enabled(): void
{
Config::set('route-statistics.store_route_parameters', true);

$route = 'home';
$params = [
'param1' => 'one',
'param2' => 'two',
];
$request = \Illuminate\Http\Request::create($route.'/'.implode('/', $this->get_route_parameters($params)), 'GET');
$this->app['router']->get($route.'/'.implode('/', $this->get_route_keys($params)), fn () => 'Test route response');
$response = $this->app['router']->dispatch($request);

(new RouteStatistic)->log($request, $response, 1, 2);

$log = RouteStatistic::first();
$this->assertEquals($params, $log->parameters);
}

public function test_logs_parameters_if_config_disabled(): void
{
Config::set('route-statistics.store_route_parameters', false);

$route = 'home';
$params = [
'param1' => 'one',
'param2' => 'two',
];
$request = \Illuminate\Http\Request::create($route.'/'.implode('/', $this->get_route_parameters($params)), 'GET');
$this->app['router']->get($route.'/'.implode('/', $this->get_route_keys($params)), fn () => 'Test route response');
$response = $this->app['router']->dispatch($request);

(new RouteStatistic)->log($request, $response, 1, 2);

$log = RouteStatistic::first();
$this->assertNull($log->parameters);
}

private function get_route_parameters(array $parameters): array
{
return array_values($parameters);
}

private function get_route_keys(array $parameters): array
{
return array_map(fn ($parameter) => '{'.$parameter.'}', array_keys($parameters));
}
}
Loading