Skip to content
Snippets Groups Projects
Commit 29aafe9f authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

Added the option to auto disable search engines

parent 54e2b9d5
No related branches found
No related tags found
No related merge requests found
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
class LogRotate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'log:rotate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Dieses Kommando bezieht alle Log-Einträge aus dem Redis System und exportiert diese in entsprechende Dateien.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
# Wir extrahieren die Logs mit den Daten der einzelnen Suchmaschinen:
# In den Daten ist festgehalten, wie oft eine jede Suchmaschine abgefragt wurde
# und wie häufig diese geantwortet hat:
$this->extractSearchEngineLogs();
}
private function extractSearchEngineLogs()
{
$redis = Redis::connection('redisLogs');
# Hier legen wir das Ergebnis ab:
# [
# 'fastbot' => [
# ''
# ]
# ]
$searchEngineLogs = ['recent' => [], 'overall' => []];
try {
# Wir benötigen zunächst die Namen aller Suchmaschinen:
$sumasFile = config_path() . "/sumas.xml";
$xml = simplexml_load_file($sumasFile);
$xml = $xml->xpath("suma");
$sumaNames = [];
foreach ($xml as $suma) {
$searchEngineLogs['recent'][$suma["name"]->__toString()] = ["requests" => 0, "answered" => 0];
}
#Auslesen/hinzufügen der Daten:
foreach ($searchEngineLogs['recent'] as $name => $values) {
$searchEngineLogs['recent'][$name]["requests"] = $redis->getset('logs.engines.requests.' . $name, 0);
$searchEngineLogs['recent'][$name]["answered"] = $redis->getset('logs.engines.answered.' . $name, 0);
}
$filePath = "/var/log/metager/";
# Wir haben nun die aktuellen daten und müssen diese noch mit den aktuellen Kombinieren:
# Hierbei behalten wir die Daten, seid dem letzten Rotate so wie sie sind und verknüpfen diese mit einer gesamt Statistik.
if (file_exists($filePath . "engine.log") && is_readable($filePath . "engine.log")) {
$oldData = file_get_contents($filePath . "engine.log");
# JSON Decode
$oldData = json_decode($oldData, true);
if (isset($oldData['overall'])) {
$searchEngineLogs['overall'] = $oldData['overall'];
}
}
# Jetzt fügen wir zu den Gesamtdaten die zuletzt erfassten hinzu:
foreach ($searchEngineLogs['recent'] as $name => $values) {
if (isset($searchEngineLogs['overall'][$name]["requests"])) {
$searchEngineLogs['overall'][$name]["requests"] += $values["requests"];
} else {
$searchEngineLogs['overall'][$name]["requests"] = $values["requests"];
}
if (isset($searchEngineLogs['overall'][$name]["answered"])) {
$searchEngineLogs['overall'][$name]["answered"] += $values["answered"];
} else {
$searchEngineLogs['overall'][$name]["answered"] = $values["answered"];
}
}
# Ins JSON Format umwandeln:
$searchEngineLogs = json_encode($searchEngineLogs, JSON_PRETTY_PRINT);
# Und in die Datei sichern
if (((file_exists($filePath . "engine.log") && is_writable($filePath . "engine.log")) || (!file_exists($filePath . "engine.log") && is_writable($filePath))) && file_put_contents($filePath . "engine.log", $searchEngineLogs) !== false) {
$this->info("Logs der Suchmaschinen erfolgreich exportiert.");
return;
} else {
# Der Schreibvorgang war nicht erfolgreich. Wir packen die Daten zurück
foreach (json_decode($searchEngineLogs, true) as $name => $values) {
$redis->incrby('logs.engines.requests.' . $name, $values["requests"]);
$redis->incrby('logs.engines.answered.' . $name, $values["answered"]);
}
$this->info("Konnte die Datei \"$filePath" . "engine.log\" nicht erstellen. Keine Rechte.");
return;
}
} catch (\ErrorException $e) {
return;
}
}
}
<?php
namespace App\Console\Commands;
use DB;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
class MonthlyRequestsGather extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'requests:gather';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Sends the gathered monthly requests from the redis to the central Database';
private $values = [];
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
# Read in the suma Files
$sumaFile = config_path('sumas.json');
$sumaEnFile = config_path('sumasEn.json');
if (file_exists($sumaFile) && file_exists($sumaEnFile)) {
$sumas = json_decode(file_get_contents($sumaFile));
$sumasEn = json_decode(file_get_contents($sumaEnFile));
$this->gatherLogs($sumas);
$this->gatherLogs($sumasEn);
foreach ($this->values as $name => $value) {
$entry = DB::table('monthlyrequests')->where(['name' => $name])->first();
$newCount = $value;
if ($entry === null) {
DB::table('monthlyrequests')->insert(['name' => $name, 'count' => $newCount]);
} else {
$newCount = $value + $entry->count;
DB::table('monthlyrequests')->where(['name' => $name])->update(['count' => $newCount]);
}
}
$this->disableOverusedEngines($sumaFile, $sumas);
$this->disableOverusedEngines($sumaEnFile, $sumasEn);
}
}
private function disableOverusedEngines($sumasFile, $sumas)
{
$currentValues = DB::table('monthlyrequests')->get();
foreach ($sumas->sumas as $sumaName => $suma) {
if (!empty($suma->disabled) && $suma->disabled === true) {
continue;
}
if (empty($suma->{"monthly-requests"})) {
continue;
}
$currentValue = 0;
foreach ($currentValues as $value) {
if ($value->name === $sumaName) {
$currentValue = $value->count;
}
}
$monthlyRequests = $suma->{"monthly-requests"};
if (!empty($suma->{"auto-disabled"}) && $suma->{"auto-disabled"} === true) {
# Maybe this engine should be enabled again
if ($currentValue < $monthlyRequests) {
unset($sumas->sumas->{$sumaName}->{"auto-disabled"});
file_put_contents($sumasFile, json_encode($sumas, JSON_PRETTY_PRINT));
}
} else if ($currentValue >= $monthlyRequests) {
$sumas->sumas->{$sumaName}->{"auto-disabled"} = true;
file_put_contents($sumasFile, json_encode($sumas, JSON_PRETTY_PRINT));
}
}
}
private function gatherLogs($sumas)
{
foreach ($sumas->sumas as $sumaName => $suma) {
if (!empty($suma->{"monthly-requests"})) {
$monthlyLimit = $suma->{"monthly-requests"};
$currentValue = Redis::get('monthlyRequests:' . $sumaName);
Redis::del('monthlyRequests:' . $sumaName);
if (empty($currentValue)) {
$currentValue = 0;
}
if (empty($this->values[$sumaName]) && $currentValue > 0) {
$this->values[$sumaName] = intval($currentValue);
}
}
}
}
}
......@@ -25,10 +25,14 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('log:rotate')->everyTenMinutes();
$schedule->command('requests:gather')->everyFifteenMinutes();
$schedule->call(function () {
DB::table('monthlyrequests')->truncate();
})->monthlyOn(1, '00:00');
// Delete all of the old humanverification entries
$schedule->call(function() {
$schedule->call(function () {
DB::delete('DELETE FROM humanverification WHERE updated_at < (now() - interval 72 hour) AND whitelist = 0 ORDER BY updated_at DESC');
DB::delete('DELETE FROM humanverification WHERE updated_at < (now() - interval 2 week) AND whitelist = 1 ORDER BY updated_at DESC');
})->everyThirtyMinutes();
......@@ -42,6 +46,6 @@ class Kernel extends ConsoleKernel
protected function commands()
{
require base_path('routes/console.php');
$this->load(__DIR__.'/Commands');
$this->load(__DIR__ . '/Commands');
}
}
......@@ -542,7 +542,8 @@ class MetaGer
foreach ($this->sumaFile->foki->{$this->fokus}->sumas as $suma) {
# Check if this engine is disabled and can't be used
$disabled = empty($this->sumaFile->sumas->{$suma}->disabled) ? false : $this->sumaFile->sumas->{$suma}->disabled;
if ($disabled) {
$autoDisabled = empty($this->sumaFile->sumas->{$suma}->{"auto-disabled"}) ? false : $this->sumaFile->sumas->{$suma}->{"auto-disabled"};
if ($disabled || $autoDisabled) {
continue;
}
......@@ -710,6 +711,11 @@ class MetaGer
foreach ($this->sumaFile->foki->{$this->fokus}->sumas as $suma) {
if ($this->sumaFile->sumas->{$suma}->{"filter-opt-in"}) {
if (!empty($filter->sumas->{$suma})) {
# If the searchengine is disabled this filter shouldn't be available
if ((!empty($this->sumaFile->sumas->{$suma}->disabled) && $this->sumaFile->sumas->{$suma}->disabled === true)
|| (!empty($this->sumaFile->sumas->{$suma}->{"auto-disabled"}) && $this->sumaFile->sumas->{$suma}->{"auto-disabled"} === true)) {
continue;
}
$availableFilter[$filterName] = $filter;
}
}
......@@ -1343,16 +1349,7 @@ class MetaGer
# 2 Arten von Logs in einem wird die Anzahl der Abfragen an eine Suchmaschine gespeichert und in der anderen
# die Anzahl, wie häufig diese Ergebnisse geliefert hat.
$enginesToLoad = $this->enginesToLoad;
$redis->pipeline(function ($pipe) use ($enginesToLoad, $logEntry) {
$pipe->rpush('logs.search', $logEntry);
foreach ($this->enginesToLoad as $name => $answered) {
$pipe->incr('logs.engines.requests.' . $name);
if ($answered) {
$pipe->incr('logs.engines.answered.' . $name);
}
}
});
$redis->rpush('logs.search', $logEntry);
} catch (\Exception $e) {
return;
}
......
......@@ -134,6 +134,12 @@ abstract class Searchengine
// each Searcher has it's own queue lying under the redis key <name>.queue
Redis::rpush($this->name . ".queue", $mission);
// The request is not cached and will be submitted to the searchengine
// We need to check if the number of requests to this engine are limited
if (!empty($this->engine->{"monthly-requests"})) {
Redis::incr("monthlyRequests:" . $this->name);
}
/**
* We have Searcher processes running for MetaGer
* Each Searcher is dedicated to one specific Searchengine and fetches it's results.
......
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Monthlyrequests extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('monthlyrequests', function (Blueprint $table) {
$table->string('name')->unique();
$table->integer('count');
$table->timestamp('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('sponsorenlinks');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment