├── CONTRIBUTING.md ├── LICENSE ├── LICENSE.md ├── README.md ├── composer.json └── src ├── Console ├── DeleteCommand.php └── IndexCommand.php ├── Drivers └── ElasticSearch.php ├── ElasticSearchAuditingServiceProvider.php ├── Jobs ├── AuditDeleteQueuedModels.php └── AuditIndexQueuedModels.php ├── Traits └── ElasticSearchAuditable.php └── config └── audit.php /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are always welcome, but to keep things organized, keep in mind the following rules. 4 | 5 | # Bug Reports 6 | 7 | When reporting a bug in the Laravel Auditing Filesystem driver package, use the [issue tracker](https://github.com/iconscout/laravel-auditing-elasticsearch/issues) of the main repository. 8 | 9 | # Pull Requests 10 | 11 | Fixing a bug, correcting a typo or adding a new feature? 12 | 13 | Just remember that all pull requests should be done against the `master` branch. 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Iconscout 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ### The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Iconscout. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Auditing Elasticsearch Driver 2 | 3 | [![Latest Unstable Version](https://poser.pugx.org/iconscout/laravel-auditing-elasticsearch/v/unstable)](https://packagist.org/packages/iconscout/laravel-auditing-elasticsearch) [![Total Downloads](https://poser.pugx.org/iconscout/laravel-auditing-elasticsearch/downloads)](https://packagist.org/packages/iconscout/laravel-auditing-elasticsearch) [![License](https://poser.pugx.org/iconscout/laravel-auditing-elasticsearch/license)](https://packagist.org/packages/iconscout/laravel-auditing-elasticsearch) 4 | 5 | This driver provides the ability to save your model audits in elasticsearch. 6 | 7 | ## Contents 8 | 9 | * [Installation](#installation) 10 | * [Setup](#setup) 11 | * [Console commands](#console-commands) 12 | * [Usage](#usage) 13 | * [Donations](#donations) 14 | 15 | ## Installation 16 | 17 | This driver requires that you are using `owen-it/laravel-auditing: ^7.0`. Provided this is fulfilled, 18 | you can install the driver like so: 19 | 20 | ``` 21 | composer require iconscout/laravel-auditing-elasticsearch 22 | ``` 23 | 24 | ## Setup 25 | 26 | You need to add the following config entries in config/audit.php if you need to change the default behaviour of the driver. 27 | The `queue` key of the config file should look like so: 28 | 29 | ``` 30 | ... 31 | 'queue' => env('AUDIT_QUEUE', true), 32 | ... 33 | ``` 34 | 35 | OR 36 | 37 | ``` 38 | ... 39 | 'queue' => env('AUDIT_QUEUE', [ 40 | 'queue' => 'default', 41 | 'connection' => 'redis' 42 | ]), 43 | ... 44 | ``` 45 | 46 | The `driver` key of the config file should look like so: 47 | 48 | ``` 49 | ... 50 | 'driver' => Iconscout\Auditing\Drivers\ElasticSearch::class, 51 | ... 52 | ``` 53 | 54 | The `drivers` key of the config file should look like so: 55 | 56 | ``` 57 | ... 58 | 'drivers' => [ 59 | 'database' => [ 60 | 'table' => 'audits', 61 | 'connection' => null, 62 | ], 63 | 'es' => [ 64 | 'client' => [ 65 | 'hosts' => [ 66 | env('AUDIT_HOST', 'localhost:9200') 67 | ] 68 | ], 69 | 'index' => env('AUDIT_INDEX', 'laravel_auditing'), 70 | 'type' => env('AUDIT_TYPE', 'audits') 71 | ], 72 | ], 73 | ... 74 | ``` 75 | 76 | ## Console commands 77 | 78 | Available artisan commands are listed below: 79 | 80 | Command | Arguments | Description 81 | --- | --- 82 | auditing:es-index | Index all of the model's records into the search index. 83 | auditing:es-delete | Delete all of the model's records from the index. 84 | 85 | For detailed description and all available options run `php artisan help [command]` in the command line. 86 | 87 | ## Usage 88 | 89 | You can use the ElasticSearch driver in any Auditable model like so in order to store audit records in elasticsearch: 90 | 91 | ``` 92 | esAudits; 148 | 149 | // Get all associated Audits via parameters ($page & $perPage) 150 | $all = $icon->esAudits($page = 1, $perPage = 10); 151 | ``` 152 | 153 | ## Donations 154 | 155 | > Help keeping the project development going, by [contributing](https://github.com/Iconscout/laravel-auditing-elasticsearch/graphs/contributors) or donating a little. 156 | > Thanks in advance. 157 | 158 | Donate directly via [Paypal](https://www.paypal.me/rankarpan) 159 | 160 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/rankarpan) 161 | 162 | More information on using customer drivers with owen-it/laravel-auditing can be found on their [homepage](http://laravel-auditing.com/docs/7.0/audit-drivers) 163 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iconscout/laravel-auditing-elasticsearch", 3 | "description": "A elasticsearch driver for the owen-it/laravel-auditing package. Allows storage of the audits in elasticsearch.", 4 | "keywords": [ 5 | "accountability", 6 | "audit", 7 | "auditing", 8 | "changes", 9 | "eloquent", 10 | "history", 11 | "log", 12 | "logging", 13 | "observer", 14 | "laravel", 15 | "lumen", 16 | "record", 17 | "revision", 18 | "tracking", 19 | "elasticsearch", 20 | "es" 21 | ], 22 | "type": "package", 23 | "repositories": [ 24 | { 25 | "packagist.org": false, 26 | "type": "vcs", 27 | "url": "https://github.com/rankarpan/laravel-auditing" 28 | } 29 | ], 30 | "license": "MIT", 31 | "support": { 32 | "issues": "https://github.com/iconscout/laravel-auditing-elasticsearch/issues", 33 | "source": "https://github.com/iconscout/laravel-auditing-elasticsearch" 34 | }, 35 | "authors": [ 36 | { 37 | "name": "Arpan Rank", 38 | "email": "arpan@iconscout.com" 39 | } 40 | ], 41 | "require": { 42 | "php": ">=7.0", 43 | "owen-it/laravel-auditing": "dev-master", 44 | "elasticsearch/elasticsearch": "6.*" 45 | }, 46 | "autoload": { 47 | "psr-4": { 48 | "Iconscout\\Auditing\\": "src/" 49 | } 50 | }, 51 | "extra": { 52 | "laravel": { 53 | "providers": [ 54 | "Iconscout\\Auditing\\ElasticSearchAuditingServiceProvider" 55 | ] 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Console/DeleteCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Console; 15 | 16 | use Illuminate\Console\Command; 17 | 18 | use Illuminate\Support\Facades\Config; 19 | use Iconscout\Auditing\Drivers\ElasticSearch; 20 | 21 | class DeleteCommand extends Command 22 | { 23 | /** 24 | * The name and signature of the console command. 25 | * 26 | * @var string 27 | */ 28 | protected $signature = 'auditing:es-delete'; 29 | 30 | /** 31 | * The console command description. 32 | * 33 | * @var string 34 | */ 35 | protected $description = "Delete all of the model's records from the index"; 36 | 37 | /** 38 | * Execute the console command. 39 | * 40 | * @return mixed 41 | */ 42 | public function handle(ElasticSearch $elasticsearch) 43 | { 44 | $index = Config::get('audit.drivers.es.index', 'laravel_auditing'); 45 | 46 | if ($elasticsearch->existsIndex()) { 47 | 48 | $elasticsearch->deleteIndex(); 49 | $this->info("The {$index} index was deleted!"); 50 | 51 | } else { 52 | $this->info("The {$index} index doesn't exist!"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Console/IndexCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Console; 15 | 16 | use Illuminate\Console\Command; 17 | 18 | use Illuminate\Support\Facades\Config; 19 | use Iconscout\Auditing\Drivers\ElasticSearch; 20 | 21 | class IndexCommand extends Command 22 | { 23 | /** 24 | * The name and signature of the console command. 25 | * 26 | * @var string 27 | */ 28 | protected $signature = 'auditing:es-index'; 29 | 30 | /** 31 | * The console command description. 32 | * 33 | * @var string 34 | */ 35 | protected $description = "Index all of the model's records into the search index"; 36 | 37 | /** 38 | * Execute the console command. 39 | * 40 | * @return mixed 41 | */ 42 | public function handle(ElasticSearch $elasticsearch) 43 | { 44 | $index = Config::get('audit.drivers.es.index', 'laravel_auditing'); 45 | 46 | if ($elasticsearch->existsIndex() === false) { 47 | 48 | $elasticsearch->createIndex(); 49 | $this->info("The {$index} index was created!"); 50 | 51 | $elasticsearch->updateAliases(); 52 | $this->info("The {$index}_write alias for the {$index} index was created!"); 53 | 54 | $elasticsearch->putMapping(); 55 | $this->info("The {$index} mapping was updated!"); 56 | 57 | } else { 58 | $this->info("The {$index} index already exist!"); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Drivers/ElasticSearch.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Drivers; 15 | 16 | use Carbon\Carbon; 17 | use Elasticsearch\ClientBuilder; 18 | use Illuminate\Support\Facades\Config; 19 | use Iconscout\Auditing\Jobs\AuditIndexQueuedModels; 20 | use Iconscout\Auditing\Jobs\AuditDeleteQueuedModels; 21 | use OwenIt\Auditing\Contracts\Audit; 22 | use OwenIt\Auditing\Contracts\Auditable; 23 | use OwenIt\Auditing\Contracts\AuditDriver; 24 | use OwenIt\Auditing\Models\Audit as AuditModel; 25 | use Ramsey\Uuid\Uuid; 26 | 27 | class ElasticSearch implements AuditDriver 28 | { 29 | /** 30 | * @var string 31 | */ 32 | protected $client = null; 33 | 34 | /** 35 | * @var string 36 | */ 37 | protected $index = null; 38 | 39 | /** 40 | * @var string 41 | */ 42 | protected $type = null; 43 | 44 | /** 45 | * ElasticSearch constructor. 46 | */ 47 | public function __construct() 48 | { 49 | $this->client = ClientBuilder::create()->setHosts(Config::get('audit.drivers.es.client.hosts', ['localhost:9200']))->build(); 50 | $this->index = Config::get('audit.drivers.es.index', 'laravel_auditing'); 51 | $this->type = Config::get('audit.drivers.es.type', 'audits'); 52 | } 53 | 54 | /** 55 | * Perform an audit. 56 | * 57 | * @param \OwenIt\Auditing\Contracts\Auditable $model 58 | * 59 | * @return \OwenIt\Auditing\Contracts\Audit 60 | */ 61 | public function audit(Auditable $model): Audit 62 | { 63 | $implementation = Config::get('audit.implementation', AuditModel::class); 64 | 65 | $this->storeAudit($model->toAudit()); 66 | 67 | return new $implementation; 68 | } 69 | 70 | /** 71 | * Remove older audits that go over the threshold. 72 | * 73 | * @param \OwenIt\Auditing\Contracts\Auditable $model 74 | * 75 | * @return bool 76 | */ 77 | public function prune(Auditable $model): bool 78 | { 79 | if ($model->getAuditThreshold() > 0) { 80 | return $this->destroyAudit($model); 81 | } 82 | 83 | return false; 84 | } 85 | 86 | public function storeAudit($model) 87 | { 88 | $model['created_at'] = Carbon::now()->toDateTimeString(); 89 | 90 | if (Config::get('audit.queue', false)) { 91 | return $this->indexQueueAuditDocument($model); 92 | } 93 | 94 | return $this->indexAuditDocument($model); 95 | } 96 | 97 | public function indexQueueAuditDocument($model) 98 | { 99 | dispatch((new AuditIndexQueuedModels($model)) 100 | ->onQueue($this->syncWithSearchUsingQueue()) 101 | ->onConnection($this->syncWithSearchUsing())); 102 | 103 | return true; 104 | } 105 | 106 | public function destroyAudit($model) 107 | { 108 | if (Config::get('audit.queue', false)) { 109 | return $this->deleteQueueAuditDocument($model); 110 | } 111 | 112 | return $this->deleteAuditDocument($model); 113 | } 114 | 115 | public function deleteQueueAuditDocument($model) 116 | { 117 | dispatch((new AuditDeleteQueuedModels($model)) 118 | ->onQueue($this->syncWithSearchUsingQueue()) 119 | ->onConnection($this->syncWithSearchUsing())); 120 | 121 | return true; 122 | } 123 | 124 | /** 125 | * Get the queue that should be used with syncing 126 | * 127 | * @return string 128 | */ 129 | public function syncWithSearchUsingQueue() 130 | { 131 | return config('audit.queue.queue'); 132 | } 133 | 134 | /** 135 | * Get the queue connection that should be used when syncing. 136 | * 137 | * @return string 138 | */ 139 | public function syncWithSearchUsing() 140 | { 141 | return config('audit.queue.connection') ?: config('queue.default'); 142 | } 143 | 144 | public function indexAuditDocument($model) 145 | { 146 | $params = [ 147 | 'index' => $this->index, 148 | 'type' => $this->type, 149 | 'id' => Uuid::uuid4(), 150 | 'body' => $model 151 | ]; 152 | 153 | try { 154 | return $this->client->index($params); 155 | } catch (\Exception $e) {} 156 | } 157 | 158 | public function searchAuditDocument($model) 159 | { 160 | $skip = $model->getAuditThreshold() - 1; 161 | 162 | $params = [ 163 | 'index' => $this->index, 164 | 'type' => $this->type, 165 | 'size' => 10000 - $skip, 166 | 'from' => $skip, 167 | 'body' => [ 168 | 'query' => [ 169 | 'bool' => [ 170 | 'must' => [ 171 | [ 172 | 'term' => [ 173 | 'auditable_id' => $model->id 174 | ] 175 | ], 176 | [ 177 | 'term' => [ 178 | 'auditable_type' => $model->getMorphClass() 179 | ] 180 | ] 181 | ] 182 | ] 183 | ], 184 | 'sort' => [ 185 | 'created_at' => [ 186 | 'order' => 'desc' 187 | ] 188 | ] 189 | ] 190 | ]; 191 | 192 | return $this->client->search($params); 193 | } 194 | 195 | public function deleteAuditDocument($model) 196 | { 197 | $audits = $this->searchAuditDocument($model); 198 | $audits = $audits['hits']['hits']; 199 | 200 | if (count($audits)) { 201 | $audit_ids = array_column($audits, '_id'); 202 | 203 | foreach ($audit_ids as $audit_id) { 204 | $params['body'][] = [ 205 | 'delete' => [ 206 | '_index' => $this->index, 207 | '_type' => $this->type, 208 | '_id' => $audit_id 209 | ] 210 | ]; 211 | 212 | } 213 | 214 | return (bool) $this->client->bulk($params); 215 | } 216 | 217 | return false; 218 | } 219 | 220 | public function createIndex() 221 | { 222 | $params = [ 223 | 'index' => $this->index, 224 | 'body' => [ 225 | 'settings' => [ 226 | 'number_of_shards' => 3, 227 | 'number_of_replicas' => 0 228 | ] 229 | ] 230 | ]; 231 | 232 | return $this->client->indices()->create($params); 233 | } 234 | 235 | public function updateAliases() 236 | { 237 | $params['body'] = [ 238 | 'actions' => [ 239 | [ 240 | 'add' => [ 241 | 'index' => $this->index, 242 | 'alias' => $this->index.'_write' 243 | ] 244 | ] 245 | ] 246 | ]; 247 | 248 | return $this->client->indices()->updateAliases($params); 249 | } 250 | 251 | public function deleteIndex() 252 | { 253 | $deleteParams = [ 254 | 'index' => $this->index 255 | ]; 256 | 257 | return $this->client->indices()->delete($deleteParams); 258 | } 259 | 260 | public function existsIndex() 261 | { 262 | $params = [ 263 | 'index' => $this->index 264 | ]; 265 | 266 | return $this->client->indices()->exists($params); 267 | } 268 | 269 | public function putMapping() 270 | { 271 | $params = [ 272 | 'index' => $this->index, 273 | 'type' => $this->type, 274 | 'body' => [ 275 | $this->type => [ 276 | '_source' => [ 277 | 'enabled' => true 278 | ], 279 | 'properties' => [ 280 | 'event' => [ 281 | 'type' => 'string', 282 | 'index' => 'not_analyzed' 283 | ], 284 | 'auditable_type' => [ 285 | 'type' => 'string', 286 | 'index' => 'not_analyzed' 287 | ], 288 | 'ip_address' => [ 289 | 'type' => 'string', 290 | 'index' => 'not_analyzed' 291 | ], 292 | 'url' => [ 293 | 'type' => 'string', 294 | 'index' => 'not_analyzed' 295 | ], 296 | 'user_agent' => [ 297 | 'type' => 'string', 298 | 'index' => 'not_analyzed' 299 | ], 300 | 'created_at' => [ 301 | 'type' => 'date', 302 | 'format' => 'yyyy-MM-dd HH:mm:ss' 303 | ], 304 | 'new_values' => [ 305 | 'properties' => [ 306 | 'created_at' => [ 307 | 'type' => 'date', 308 | 'format' => 'yyyy-MM-dd HH:mm:ss' 309 | ], 310 | 'updated_at' => [ 311 | 'type' => 'date', 312 | 'format' => 'yyyy-MM-dd HH:mm:ss' 313 | ], 314 | 'deleted_at' => [ 315 | 'type' => 'date', 316 | 'format' => 'yyyy-MM-dd HH:mm:ss' 317 | ] 318 | ] 319 | ], 320 | 'old_values' => [ 321 | 'properties' => [ 322 | 'created_at' => [ 323 | 'type' => 'date', 324 | 'format' => 'yyyy-MM-dd HH:mm:ss' 325 | ], 326 | 'updated_at' => [ 327 | 'type' => 'date', 328 | 'format' => 'yyyy-MM-dd HH:mm:ss' 329 | ], 330 | 'deleted_at' => [ 331 | 'type' => 'date', 332 | 'format' => 'yyyy-MM-dd HH:mm:ss' 333 | ] 334 | ] 335 | ] 336 | ] 337 | ] 338 | ] 339 | ]; 340 | 341 | return $this->client->indices()->putMapping($params); 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /src/ElasticSearchAuditingServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing; 15 | 16 | use Illuminate\Support\ServiceProvider; 17 | 18 | use Iconscout\Auditing\Console\IndexCommand; 19 | use Iconscout\Auditing\Console\DeleteCommand; 20 | 21 | class ElasticSearchAuditingServiceProvider extends ServiceProvider 22 | { 23 | /** 24 | * Register the service provider. 25 | * 26 | * @return void 27 | */ 28 | public function register() 29 | { 30 | if ($this->app->runningInConsole()) { 31 | $this->commands([ 32 | IndexCommand::class, 33 | DeleteCommand::class, 34 | ]); 35 | 36 | $this->publishes([ 37 | __DIR__.'/config/audit.php' => $this->app['path.config'].DIRECTORY_SEPARATOR.'audit.php', 38 | ]); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Jobs/AuditDeleteQueuedModels.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Jobs; 15 | 16 | use Illuminate\Bus\Queueable; 17 | use Illuminate\Queue\SerializesModels; 18 | use Illuminate\Queue\InteractsWithQueue; 19 | use Illuminate\Contracts\Queue\ShouldQueue; 20 | 21 | use Iconscout\Auditing\Drivers\ElasticSearch; 22 | 23 | class AuditDeleteQueuedModels implements ShouldQueue 24 | { 25 | use InteractsWithQueue, Queueable, SerializesModels; 26 | 27 | /** 28 | * @var 29 | */ 30 | private $model; 31 | 32 | /** 33 | * Create a new job instance. 34 | * 35 | * @param mixed $model 36 | * 37 | * @return void 38 | */ 39 | public function __construct($model) 40 | { 41 | $this->model = $model; 42 | } 43 | 44 | /** 45 | * Audit the model auditable. 46 | * 47 | * @param \OwenIt\Auditing\AuditorManager $manager 48 | * 49 | * @return void 50 | */ 51 | public function handle(ElasticSearch $elasticsearch) 52 | { 53 | $elasticsearch->deleteAuditDocument($this->model); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Jobs/AuditIndexQueuedModels.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Jobs; 15 | 16 | use Illuminate\Bus\Queueable; 17 | use Illuminate\Queue\SerializesModels; 18 | use Illuminate\Queue\InteractsWithQueue; 19 | use Illuminate\Contracts\Queue\ShouldQueue; 20 | 21 | use Iconscout\Auditing\Drivers\ElasticSearch; 22 | 23 | class AuditIndexQueuedModels implements ShouldQueue 24 | { 25 | use InteractsWithQueue, Queueable, SerializesModels; 26 | 27 | /** 28 | * @var 29 | */ 30 | private $model; 31 | 32 | /** 33 | * Create a new job instance. 34 | * 35 | * @param mixed $model 36 | * 37 | * @return void 38 | */ 39 | public function __construct($model) 40 | { 41 | $this->model = $model; 42 | } 43 | 44 | /** 45 | * Audit the model auditable. 46 | * 47 | * @param \OwenIt\Auditing\AuditorManager $manager 48 | * 49 | * @return void 50 | */ 51 | public function handle(ElasticSearch $elasticsearch) 52 | { 53 | $elasticsearch->indexAuditDocument($this->model); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Traits/ElasticSearchAuditable.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | namespace Iconscout\Auditing\Traits; 15 | 16 | use Elasticsearch\ClientBuilder; 17 | use Illuminate\Support\Facades\Config; 18 | use Illuminate\Database\Eloquent\Collection; 19 | 20 | trait ElasticSearchAuditable 21 | { 22 | public function esAudits($page = 1, $perPage = 10, $sort = 'latest') 23 | { 24 | $client = ClientBuilder::create()->setHosts(Config::get('audit.drivers.es.client.hosts', ['localhost:9200']))->build(); 25 | $index = Config::get('audit.drivers.es.index', 'laravel_auditing'); 26 | $type = Config::get('audit.drivers.es.type', 'audits'); 27 | 28 | $from = ($page - 1) * $perPage; 29 | $order = $sort === 'latest' ? 'desc' : 'asc'; 30 | 31 | $params = [ 32 | 'index' => $index, 33 | 'type' => $type, 34 | 'size' => $perPage, 35 | 'from' => $from, 36 | 'body' => [ 37 | 'query' => [ 38 | 'bool' => [ 39 | 'must' => [ 40 | [ 41 | 'term' => [ 42 | 'auditable_id' => $this->id 43 | ] 44 | ], 45 | [ 46 | 'term' => [ 47 | 'auditable_type' => $this->getMorphClass() 48 | ] 49 | ] 50 | ] 51 | ] 52 | ], 53 | 'sort' => [ 54 | 'created_at' => [ 55 | 'order' => $order 56 | ] 57 | ], 58 | 'track_scores' => true 59 | ] 60 | ]; 61 | 62 | $results = $client->search($params); 63 | $hits = $results['hits']; 64 | 65 | $collection = Collection::make(); 66 | 67 | foreach ($hits['hits'] as $key => $result) { 68 | $audit['id'] = $result['_id']; 69 | $audit = array_merge($audit, $result['_source']); 70 | $audit['score'] = $result['_score']; 71 | 72 | $collection->put($key, $audit); 73 | } 74 | 75 | return [ 76 | 'total' => $hits['total'], 77 | 'per_page' => $perPage, 78 | 'data' => $collection 79 | ]; 80 | } 81 | 82 | public function getEsAuditsAttribute() 83 | { 84 | return $this->esAudits(); 85 | } 86 | } -------------------------------------------------------------------------------- /src/config/audit.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2018 8 | * 9 | * For the full copyright and license information, 10 | * please view the LICENSE.md file that was distributed 11 | * with this source code. 12 | */ 13 | 14 | return [ 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Audit Implementation 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Define which Audit model implementation should be used. 22 | | 23 | */ 24 | 25 | 'implementation' => OwenIt\Auditing\Models\Audit::class, 26 | 27 | /* 28 | |-------------------------------------------------------------------------- 29 | | User Keys, Model 30 | |-------------------------------------------------------------------------- 31 | | 32 | | Define the User primary key, foreign key and Eloquent model. 33 | | 34 | */ 35 | 36 | 'user' => [ 37 | 'primary_key' => 'id', 38 | 'foreign_key' => 'user_id', 39 | 'model' => App\Models\User::class, 40 | ], 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | Audit Resolvers 45 | |-------------------------------------------------------------------------- 46 | | 47 | | Define the User, IP Address, User Agent and URL resolver implementations. 48 | | 49 | */ 50 | 'resolver' => [ 51 | 'user' => OwenIt\Auditing\Resolvers\UserResolver::class, 52 | 'ip_address' => OwenIt\Auditing\Resolvers\IpAddressResolver::class, 53 | 'user_agent' => OwenIt\Auditing\Resolvers\UserAgentResolver::class, 54 | 'url' => OwenIt\Auditing\Resolvers\UrlResolver::class, 55 | ], 56 | 57 | /* 58 | |-------------------------------------------------------------------------- 59 | | Audit Events 60 | |-------------------------------------------------------------------------- 61 | | 62 | | The Eloquent events that trigger an Audit. 63 | | 64 | */ 65 | 66 | 'events' => [ 67 | 'created', 68 | 'updated', 69 | 'deleted', 70 | 'restored', 71 | ], 72 | 73 | /* 74 | |-------------------------------------------------------------------------- 75 | | Strict Mode 76 | |-------------------------------------------------------------------------- 77 | | 78 | | Enable the strict mode when auditing? 79 | | 80 | */ 81 | 82 | 'strict' => env('AUDIT_STRICT', false), 83 | 84 | /* 85 | |-------------------------------------------------------------------------- 86 | | Audit Timestamps 87 | |-------------------------------------------------------------------------- 88 | | 89 | | Should the created_at, updated_at and deleted_at timestamps be audited? 90 | | 91 | */ 92 | 93 | 'timestamps' => env('AUDIT_TIMESTAMPS', true), 94 | 95 | /* 96 | |-------------------------------------------------------------------------- 97 | | Audit Threshold 98 | |-------------------------------------------------------------------------- 99 | | 100 | | Specify a threshold for the amount of Audit records a model can have. 101 | | Zero means no limit. 102 | | 103 | */ 104 | 105 | 'threshold' => env('AUDIT_THRESHOLD', 0), 106 | 107 | /* 108 | |-------------------------------------------------------------------------- 109 | | Queue Auditable Models 110 | |-------------------------------------------------------------------------- 111 | | 112 | | This option allows you to control if the operations that audit your models 113 | | with your auditors are queued. When this is set to "true" then all models 114 | | auditable will get queued for better performance. 115 | | 116 | */ 117 | 118 | 'queue' => env('AUDIT_QUEUE', true), 119 | 120 | /* 121 | |-------------------------------------------------------------------------- 122 | | Audit Driver 123 | |-------------------------------------------------------------------------- 124 | | 125 | | The default audit driver used to keep track of changes. 126 | | 127 | */ 128 | 129 | 'driver' => Iconscout\Auditing\Drivers\ElasticSearch::class, 130 | 131 | /* 132 | |-------------------------------------------------------------------------- 133 | | Audit Driver Configurations 134 | |-------------------------------------------------------------------------- 135 | | 136 | | Available audit drivers and respective configurations. 137 | | 138 | */ 139 | 140 | 'drivers' => [ 141 | 'database' => [ 142 | 'table' => 'audits', 143 | 'connection' => null, 144 | ], 145 | 'es' => [ 146 | 'client' => [ 147 | 'hosts' => [ 148 | env('AUDIT_HOST', 'localhost:9200') 149 | ] 150 | ], 151 | 'index' => env('AUDIT_INDEX', 'laravel_auditing'), 152 | 'type' => env('AUDIT_TYPE', 'audits') 153 | ] 154 | ], 155 | 156 | /* 157 | |-------------------------------------------------------------------------- 158 | | Audit Console 159 | |-------------------------------------------------------------------------- 160 | | 161 | | Whether console events should be audited (eg. php artisan db:seed). 162 | | 163 | */ 164 | 165 | 'console' => false, 166 | ]; 167 | --------------------------------------------------------------------------------