AdminInterface.php 10.5 KB
Newer Older
1 2 3 4
<?php

namespace App\Http\Controllers;

5
use App\Jobs\ConvertCountFile;
Dominik Hebeler's avatar
Dominik Hebeler committed
6
use Carbon\Carbon;
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Facades\Redis;
9
use Response;
10 11 12

class AdminInterface extends Controller
{
Dominik Hebeler's avatar
Dominik Hebeler committed
13
    public function index(Request $request)
14 15 16 17 18 19 20
    {
        // Let's get the stats for this server.
        // First we need to check, which Fetcher could be available by parsing the sumas.xml
        $names = $this->getSearchEngineNames();

        // Now we gonna check which stats we can find
        $stati = array();
Dominik Hebeler's avatar
Dominik Hebeler committed
21
        foreach ($names as $name) {
22
            $stats = Redis::hgetall($name . ".stats");
Dominik Hebeler's avatar
Dominik Hebeler committed
23
            if (sizeof($stats) > 0) {
24 25
                $fetcherStatus = Redis::get($name);
                $stati[$name]["status"] = $fetcherStatus;
Dominik Hebeler's avatar
Dominik Hebeler committed
26 27
                foreach ($stats as $pid => $value) {
                    if (strstr($value, ";")) {
28 29
                        $value = explode(";", $value);
                        $connection = json_decode(base64_decode($value[0]), true);
Dominik Hebeler's avatar
Dominik Hebeler committed
30 31
                        foreach ($connection as $key => $val) {
                            if (strstr($key, "_time")) {
32
                                $stati[$name]["fetcher"][$pid]["connection"][$key] = $val;
Dominik Hebeler's avatar
Dominik Hebeler committed
33 34
                            }

35 36 37
                        }
                        $stati[$name]["fetcher"][$pid]["poptime"] = $value[1];
                    }
Dominik Hebeler's avatar
Dominik Hebeler committed
38
                }
39 40
            }
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
41

42
        // So now we can generate Median Times for every Fetcher
Dominik Hebeler's avatar
Dominik Hebeler committed
43
        $fetcherCount = 0;
Dominik Hebeler's avatar
Dominik Hebeler committed
44
        foreach ($stati as $engineName => $engineStats) {
45 46
            $connection = array();
            $poptime = 0;
Dominik Hebeler's avatar
Dominik Hebeler committed
47
            $fetcherCount += sizeof($engineStats["fetcher"]);
Dominik Hebeler's avatar
Dominik Hebeler committed
48 49 50
            foreach ($engineStats["fetcher"] as $pid => $stats) {
                foreach ($stats["connection"] as $key => $value) {
                    if (!isset($connection[$key])) {
51
                        $connection[$key] = $value;
Dominik Hebeler's avatar
Dominik Hebeler committed
52
                    } else {
53 54 55 56
                        $connection[$key] += $value;
                    }
                }
                $poptime += floatval($stats["poptime"]);
57
            }
Dominik Hebeler's avatar
Dominik Hebeler committed
58
            foreach ($connection as $key => $value) {
59 60 61 62 63 64
                $connection[$key] /= sizeof($engineStats["fetcher"]);
            }
            $poptime /= sizeof($engineStats["fetcher"]);

            $stati[$engineName]["median-connection"] = $connection;
            $stati[$engineName]["median-poptime"] = $poptime;
Dominik Hebeler's avatar
Dominik Hebeler committed
65
        }
66

Dominik Hebeler's avatar
Dominik Hebeler committed
67
        return view('admin.admin')
68
            ->with('title', 'Fetcher Status')
Dominik Hebeler's avatar
Dominik Hebeler committed
69 70
            ->with('stati', $stati)
            ->with('fetcherCount', $fetcherCount);
71 72 73 74 75 76
        $stati = json_encode($stati);
        $response = Response::make($stati, 200);
        $response->header("Content-Type", "application/json");
        return $response;
    }

Dominik Hebeler's avatar
Dominik Hebeler committed
77 78
    private function getSearchEngineNames()
    {
79 80 81 82 83
        $url = config_path() . "/sumas.xml";
        $xml = simplexml_load_file($url);
        $sumas = $xml->xpath("suma");

        $names = array();
Dominik Hebeler's avatar
Dominik Hebeler committed
84
        foreach ($sumas as $suma) {
85 86 87
            $names[] = $suma["name"]->__toString();
        }
        return $names;
88
    }
89

90
    public function count(Request $request)
91
    {
92
        $days = intval($request->input('days', 28));
Dominik Hebeler's avatar
Dominik Hebeler committed
93 94 95 96 97
        $interface = $request->input('interface', 'all');
        if (!is_int($days) || $days <= 0) {
            $days = 28;
        }

98 99 100 101 102 103
        $maxDate = Carbon::createFromFormat('d.m.Y', "28.06.2016");
        $selectedDate = Carbon::now()->subDays($days);
        if ($maxDate > $selectedDate) {
            $days = $maxDate->diffInDays(Carbon::now());
        }

Dominik Hebeler's avatar
Dominik Hebeler committed
104 105
        $logToday = "/var/log/metager/mg3.log";

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
        $archivePath = "/var/log/metager/archive/";

        $today = [
            'logFile' => $logToday,
            'countPath' => storage_path('logs/count/'),
            'countFile' => storage_path('logs/count/' . getmypid()),
        ];
        if (\file_exists($today["countFile"])) {
            unlink($today["countFile"]);
        }

        $neededLogs = [
            0 => $today,
        ];
        $logsToRequest = [
            0 => $today,
        ];
        $requestedLogs = [];
        for ($i = 1; $i <= $days; $i++) {
            $date = Carbon::now()->subDays($i);
            $countPath = storage_path('logs/count/' . $date->year . "/" . $date->month . "/");
            $countFile = $countPath . $date->day . ".json";
            $neededLogs[$i] = [
                'logFile' => $archivePath . "mg3.log.$i",
                'countPath' => $countPath,
                'countFile' => $countFile,
            ];
            if (!file_exists($neededLogs[$i]['countFile'])) {
                $logsToRequest[$i] = $neededLogs[$i];
            }
        }
        if (sizeof($logsToRequest) > 100) {
            set_time_limit(600);
        }
        // Create the Jobs for count file creation
        while (sizeof($logsToRequest) > 0 || sizeof($requestedLogs) > 0) {
            if (sizeof($requestedLogs) < 20 && sizeof($logsToRequest) > 0) {
                $newJob = array_shift($logsToRequest);
                $newJob["startedAt"] = time();
                $requestedLogs[] = $newJob;

                Redis::set(md5($newJob["countFile"]), "running");
                Redis::expire(md5($newJob["countFile"]), 15);
                ConvertCountFile::dispatch($newJob);
Dominik Hebeler's avatar
Dominik Hebeler committed
150
            } else {
151
                usleep(50000);
Dominik Hebeler's avatar
Dominik Hebeler committed
152
            }
153 154 155 156 157 158 159 160 161 162 163 164
            // Remove all finished Jobs
            $removedOne = false;
            do {
                $removedOne = false;
                foreach ($requestedLogs as $index => $requestedLog) {
                    if (!Redis::exists(md5($requestedLog["countFile"]))) {
                        unset($requestedLogs[$index]);
                        $removedOne = true;
                        break;
                    }
                }
            } while ($removedOne === true);
165
        }
166

Dominik Hebeler's avatar
Dominik Hebeler committed
167 168
        $oldLogs = [];
        $rekordTag = 0;
169
        $minCount = 0;
170
        $rekordTagDate = "";
Dominik Hebeler's avatar
Dominik Hebeler committed
171 172
        $size = 0;
        $count = 0;
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

        $now = Carbon::now()->subMinutes(Carbon::now()->minute % 5)->format('H:i');
        if ($now === "00:00") {
            $now = "00:05";
        }

        foreach ($neededLogs as $key => $value) {
            $countFile = $value["countFile"];
            if (file_exists($countFile)) {
                $stats = json_decode(file_get_contents($countFile));
                if ($key === 0) {
                    // Log for today
                    $logToday = empty($stats->insgesamt->{$interface}) ? 0 : $stats->insgesamt->{$interface};
                    if (\file_exists($today["countFile"])) {
                        unlink($today["countFile"]);
                    }
                    continue;
Dominik Hebeler's avatar
Dominik Hebeler committed
190
                }
191 192 193
                $insgesamt = empty($stats->insgesamt->{$interface}) ? 0 : $stats->insgesamt->{$interface};
                $sameTime = empty($stats->time->{$now}->{$interface}) ? 0 : $stats->time->{$now}->{$interface};

Dominik Hebeler's avatar
Dominik Hebeler committed
194
                if ($insgesamt > $rekordTag) {
Dominik Hebeler's avatar
Dominik Hebeler committed
195
                    $rekordTag = $insgesamt;
196
                    $rekordTagSameTime = $sameTime;
Dominik Hebeler's avatar
Dominik Hebeler committed
197
                    $rekordTagDate = Carbon::now()->subDays($key)->format('d.m.Y');
198
                }
199 200 201
                if ($minCount === 0 || $insgesamt < $minCount) {
                    $minCount = $insgesamt;
                }
202 203
                $oldLogs[$key]['sameTime'] = number_format(floatval($sameTime), 0, ",", ".");
                $oldLogs[$key]['insgesamt'] = number_format(floatval($insgesamt), 0, ",", ".");
Dominik Hebeler's avatar
Dominik Hebeler committed
204 205
                # Nun noch den median:
                $count += $insgesamt;
206
                $size++;
Dominik Hebeler's avatar
Dominik Hebeler committed
207
                if ($size > 0) {
208
                    $oldLogs[$key]['median'] = number_format(floatval(round($count / $size)), 0, ",", ".");
Dominik Hebeler's avatar
Dominik Hebeler committed
209 210
                }

211
            }
212 213
        }

Dominik Hebeler's avatar
Dominik Hebeler committed
214
        if ($request->input('out', 'web') === "web") {
215 216
            return view('admin.count')
                ->with('title', 'Suchanfragen - MetaGer')
Dominik Hebeler's avatar
Dominik Hebeler committed
217
                ->with('today', number_format(floatval($logToday), 0, ",", "."))
218
                ->with('oldLogs', $oldLogs)
219
                ->with('minCount', $minCount)
220 221 222 223
                ->with('rekordCount', number_format(floatval($rekordTag), 0, ",", "."))
                ->with('rekordTagSameTime', number_format(floatval($rekordTagSameTime), 0, ",", "."))
                ->with('rekordDate', $rekordTagDate)
                ->with('days', $days);
Dominik Hebeler's avatar
Dominik Hebeler committed
224 225 226 227 228 229 230 231 232 233 234 235
        } else {
            $result = "";
            foreach ($oldLogs as $key => $value) {
                $resultTmp = '"' . date("D, d M y", mktime(date("H"), date("i"), date("s"), date("m"), date("d") - $key, date("Y"))) . '",';
                $resultTmp .= '"' . $value['sameTime'] . '",';
                $resultTmp .= '"' . $value['insgesamt'] . '",';
                $resultTmp .= '"' . $value['median'] . '"' . "\r\n";
                $result = $resultTmp . $result;
            }
            return response($result, 200)
                ->header('Content-Type', 'text/csv')
                ->header('Content-Disposition', 'attachment; filename="count.csv"');
Dominik Hebeler's avatar
Dominik Hebeler committed
236

237 238
        }

239
    }
Dominik Hebeler's avatar
Dominik Hebeler committed
240

Dominik Hebeler's avatar
Dominik Hebeler committed
241
    public function check()
242
    {
Dominik Hebeler's avatar
Dominik Hebeler committed
243
        $q = "";
244
        $redis = Redis::connection('redisLogs');
Dominik Hebeler's avatar
Dominik Hebeler committed
245
        if ($redis) {
246
            $q = $redis->lrange("logs.search", -1, -1)[0];
Dominik Hebeler's avatar
Dominik Hebeler committed
247
            $q = substr($q, strpos($q, "search=") + 7);
248 249 250 251 252
        }
        return view('admin.check')
            ->with('title', 'Wer sucht was? - MetaGer')
            ->with('q', $q);
    }
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285

    public function engines()
    {
        # Wir laden den Inhalt der Log Datei und übergeben ihn an den view
        $file = "/var/log/metager/engine.log";
        if (file_exists($file) && is_readable($file)) {
            $engineStats = file_get_contents($file);
            # Daten vom JSON Format dekodieren
            $engineStats = json_decode($engineStats, true);

            # Eine Sortierung wäre nicht das verkehrteste
            uasort($engineStats["recent"], function ($a, $b) {
                if ($a["requests"] == $b["requests"]) {
                    return 0;
                }

                return ($a["requests"] < $b["requests"]) ? 1 : -1;
            });

            uasort($engineStats["overall"], function ($a, $b) {
                if ($a["requests"] == $b["requests"]) {
                    return 0;
                }

                return ($a["requests"] < $b["requests"]) ? 1 : -1;
            });
            return view('admin.engines')
                ->with('engineStats', $engineStats)
                ->with('title', "Suchmaschinenstatus - MetaGer");
        } else {
            return redirect(url('admin'));
        }
    }
286
}