metrics: Added more stats
This commit is contained in:
parent
c5621b82cf
commit
9a2f246511
|
@ -7,6 +7,7 @@ use Engelsystem\Controllers\BaseController;
|
|||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
|
@ -62,6 +63,15 @@ class Controller extends BaseController
|
|||
['labels' => ['state' => 'arrived', 'working' => 'no'], 'value' => $this->stats->arrivedUsers(false)],
|
||||
['labels' => ['state' => 'arrived', 'working' => 'yes'], 'value' => $this->stats->arrivedUsers(true)],
|
||||
],
|
||||
'licenses' => [
|
||||
'type' => 'gauge',
|
||||
'help' => 'The total number of licenses',
|
||||
['labels' => ['type' => 'forklift'], 'value' => $this->stats->licenses('forklift')],
|
||||
['labels' => ['type' => 'car'], 'value' => $this->stats->licenses('car')],
|
||||
['labels' => ['type' => '3.5t'], 'value' => $this->stats->licenses('3.5t')],
|
||||
['labels' => ['type' => '7.5t'], 'value' => $this->stats->licenses('7.5t')],
|
||||
['labels' => ['type' => '12.5t'], 'value' => $this->stats->licenses('12.5t')],
|
||||
],
|
||||
'users_working' => [
|
||||
'type' => 'gauge',
|
||||
['labels' => ['freeloader' => false], $this->stats->currentlyWorkingUsers(false)],
|
||||
|
@ -73,7 +83,36 @@ class Controller extends BaseController
|
|||
['labels' => ['state' => 'planned'], 'value' => $this->stats->workSeconds(false, false)],
|
||||
['labels' => ['state' => 'freeloaded'], 'value' => $this->stats->workSeconds(null, true)],
|
||||
],
|
||||
'worklog_seconds' => ['type' => 'gauge', $this->stats->worklogSeconds()],
|
||||
'shifts' => ['type' => 'gauge', $this->stats->shifts()],
|
||||
'announcements' => [
|
||||
'type' => 'gauge',
|
||||
['labels' => ['type' => 'news'], 'value' => $this->stats->announcements(false)],
|
||||
['labels' => ['type' => 'meeting'], 'value' => $this->stats->announcements(true)],
|
||||
],
|
||||
'questions' => [
|
||||
'type' => 'gauge',
|
||||
['labels' => ['answered' => true], 'value' => $this->stats->questions(true)],
|
||||
['labels' => ['answered' => false], 'value' => $this->stats->questions(false)],
|
||||
],
|
||||
'messages' => ['type' => 'gauge', $this->stats->messages()],
|
||||
'password_resets' => ['type' => 'gauge', $this->stats->passwordResets()],
|
||||
'registration_enabled' => ['type' => 'gauge', $this->config->get('registration_enabled')],
|
||||
'sessions' => ['type' => 'gauge', $this->stats->sessions()],
|
||||
'log_entries' => [
|
||||
'type' => 'counter',
|
||||
[
|
||||
'labels' => ['level' => LogLevel::EMERGENCY],
|
||||
'value' => $this->stats->logEntries(LogLevel::EMERGENCY)
|
||||
],
|
||||
['labels' => ['level' => LogLevel::ALERT], 'value' => $this->stats->logEntries(LogLevel::ALERT)],
|
||||
['labels' => ['level' => LogLevel::CRITICAL], 'value' => $this->stats->logEntries(LogLevel::CRITICAL)],
|
||||
['labels' => ['level' => LogLevel::ERROR], 'value' => $this->stats->logEntries(LogLevel::ERROR)],
|
||||
['labels' => ['level' => LogLevel::WARNING], 'value' => $this->stats->logEntries(LogLevel::WARNING)],
|
||||
['labels' => ['level' => LogLevel::NOTICE], 'value' => $this->stats->logEntries(LogLevel::NOTICE)],
|
||||
['labels' => ['level' => LogLevel::INFO], 'value' => $this->stats->logEntries(LogLevel::INFO)],
|
||||
['labels' => ['level' => LogLevel::DEBUG], 'value' => $this->stats->logEntries(LogLevel::DEBUG)],
|
||||
],
|
||||
];
|
||||
|
||||
$data['scrape_duration_seconds'] = [
|
||||
|
|
|
@ -96,6 +96,31 @@ class Stats
|
|||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $vehicle
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function licenses($vehicle = null)
|
||||
{
|
||||
$mapping = [
|
||||
'forklift' => 'has_license_forklift',
|
||||
'car' => 'has_license_car',
|
||||
'3.5t' => 'has_license_3_5t_transporter',
|
||||
'7.5t' => 'has_license_7_5t_truck',
|
||||
'12.5t' => 'has_license_12_5t_truck',
|
||||
];
|
||||
|
||||
$query = $this
|
||||
->getQuery('UserDriverLicenses');
|
||||
|
||||
if (!is_null($vehicle)) {
|
||||
$query->where($mapping[$vehicle], '=', true);
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of worked shifts
|
||||
*
|
||||
|
@ -121,6 +146,113 @@ class Stats
|
|||
return $query->sum($this->raw('end - start'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function worklogSeconds()
|
||||
{
|
||||
return round($this
|
||||
->getQuery('UserWorkLog')
|
||||
->sum($this->raw('work_hours * 60*60')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function shifts()
|
||||
{
|
||||
return $this
|
||||
->getQuery('Shifts')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $meeting
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function announcements($meeting = null)
|
||||
{
|
||||
$query = $this
|
||||
->getQuery('News');
|
||||
|
||||
if (!is_null($meeting)) {
|
||||
$query->where('Treffen', '=', $meeting);
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $answered
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function questions($answered = null)
|
||||
{
|
||||
$query = $this
|
||||
->getQuery('Questions');
|
||||
|
||||
if (!is_null($answered)) {
|
||||
if ($answered) {
|
||||
$query->whereNotNull('AID');
|
||||
} else {
|
||||
$query->whereNull('AID');
|
||||
}
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
return $this
|
||||
->getQuery('Messages')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function sessions()
|
||||
{
|
||||
return $this
|
||||
->getQuery('sessions')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
* @return int
|
||||
*/
|
||||
public function logEntries($level = null)
|
||||
{
|
||||
$query = $this
|
||||
->getQuery('log_entries');
|
||||
|
||||
if (!is_null($level)) {
|
||||
$query->where('level', '=', $level);
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function passwordResets()
|
||||
{
|
||||
return $this
|
||||
->getQuery('password_resets')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @return QueryBuilder
|
||||
|
|
|
@ -11,6 +11,7 @@ use Engelsystem\Http\Request;
|
|||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Component\HttpFoundation\ServerBag;
|
||||
|
||||
class ControllerTest extends TestCase
|
||||
|
@ -36,9 +37,18 @@ class ControllerTest extends TestCase
|
|||
->willReturnCallback(function ($path, $data) use ($response) {
|
||||
$this->assertEquals('/metrics', $path);
|
||||
$this->assertArrayHasKey('users', $data);
|
||||
$this->assertArrayHasKey('licenses', $data);
|
||||
$this->assertArrayHasKey('users_working', $data);
|
||||
$this->assertArrayHasKey('work_seconds', $data);
|
||||
$this->assertArrayHasKey('worklog_seconds', $data);
|
||||
$this->assertArrayHasKey('shifts', $data);
|
||||
$this->assertArrayHasKey('announcements', $data);
|
||||
$this->assertArrayHasKey('questions', $data);
|
||||
$this->assertArrayHasKey('messages', $data);
|
||||
$this->assertArrayHasKey('password_resets', $data);
|
||||
$this->assertArrayHasKey('registration_enabled', $data);
|
||||
$this->assertArrayHasKey('sessions', $data);
|
||||
$this->assertArrayHasKey('log_entries', $data);
|
||||
$this->assertArrayHasKey('scrape_duration_seconds', $data);
|
||||
|
||||
return 'metrics return';
|
||||
|
@ -53,6 +63,10 @@ class ControllerTest extends TestCase
|
|||
->with('metrics return')
|
||||
->willReturn($response);
|
||||
|
||||
$stats->expects($this->exactly(5))
|
||||
->method('licenses')
|
||||
->withConsecutive(['forklift'], ['car'], ['3.5t'], ['7.5t'], ['12.5t'])
|
||||
->willReturnOnConsecutiveCalls(3, 15, 9, 7, 1);
|
||||
$stats->expects($this->exactly(2))
|
||||
->method('arrivedUsers')
|
||||
->withConsecutive([false], [true])
|
||||
|
@ -65,7 +79,33 @@ class ControllerTest extends TestCase
|
|||
->method('workSeconds')
|
||||
->withConsecutive([true, false], [false, false], [null, true])
|
||||
->willReturnOnConsecutiveCalls(60 * 37, 60 * 251, 60 * 3);
|
||||
$stats->expects($this->exactly(2))
|
||||
->method('announcements')
|
||||
->withConsecutive([false], [true])
|
||||
->willReturnOnConsecutiveCalls(18, 7);
|
||||
$stats->expects($this->exactly(2))
|
||||
->method('questions')
|
||||
->withConsecutive([true], [false])
|
||||
->willReturnOnConsecutiveCalls(5, 0);
|
||||
$stats->expects($this->exactly(8))
|
||||
->method('logEntries')
|
||||
->withConsecutive(
|
||||
[LogLevel::EMERGENCY],
|
||||
[LogLevel::ALERT],
|
||||
[LogLevel::CRITICAL],
|
||||
[LogLevel::ERROR],
|
||||
[LogLevel::WARNING],
|
||||
[LogLevel::NOTICE],
|
||||
[LogLevel::INFO],
|
||||
[LogLevel::DEBUG]
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(0, 1, 0, 5, 999, 4, 55, 3);
|
||||
$this->setExpects($stats, 'newUsers', null, 9);
|
||||
$this->setExpects($stats, 'worklogSeconds', null, 39 * 60 * 60);
|
||||
$this->setExpects($stats, 'shifts', null, 142);
|
||||
$this->setExpects($stats, 'messages', null, 3);
|
||||
$this->setExpects($stats, 'passwordResets', null, 1);
|
||||
$this->setExpects($stats, 'sessions', null, 1234);
|
||||
|
||||
$config->set('registration_enabled', 1);
|
||||
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
namespace Engelsystem\Test\Unit\Controllers\Metrics;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Controllers\Metrics\Stats;
|
||||
use Engelsystem\Models\LogEntry;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
use Engelsystem\Models\User\State;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class StatsTest extends TestCase
|
||||
{
|
||||
|
@ -39,6 +43,62 @@ class StatsTest extends TestCase
|
|||
$this->assertEquals(3, $stats->arrivedUsers());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::sessions
|
||||
*/
|
||||
public function testSessions()
|
||||
{
|
||||
$this->initDatabase();
|
||||
|
||||
$this->database
|
||||
->getConnection()
|
||||
->table('sessions')
|
||||
->insert([
|
||||
['id' => 'asd', 'payload' => 'data', 'last_activity' => new Carbon('1 month ago')],
|
||||
['id' => 'efg', 'payload' => 'lorem', 'last_activity' => new Carbon('55 minutes ago')],
|
||||
['id' => 'hij', 'payload' => 'ipsum', 'last_activity' => new Carbon('3 seconds ago')],
|
||||
['id' => 'klm', 'payload' => 'dolor', 'last_activity' => new Carbon()],
|
||||
]);
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$this->assertEquals(4, $stats->sessions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::logEntries
|
||||
*/
|
||||
public function testLogEntries()
|
||||
{
|
||||
$this->initDatabase();
|
||||
|
||||
(new LogEntry(['level' => LogLevel::INFO, 'message' => 'Some info']))->save();
|
||||
(new LogEntry(['level' => LogLevel::INFO, 'message' => 'Another info']))->save();
|
||||
(new LogEntry(['level' => LogLevel::CRITICAL, 'message' => 'A critical error!']))->save();
|
||||
(new LogEntry(['level' => LogLevel::DEBUG, 'message' => 'Verbose output!']))->save();
|
||||
(new LogEntry(['level' => LogLevel::INFO, 'message' => 'Shutdown initiated']))->save();
|
||||
(new LogEntry(['level' => LogLevel::WARNING, 'message' => 'Please be cautious']))->save();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$this->assertEquals(6, $stats->logEntries());
|
||||
$this->assertEquals(3, $stats->logEntries(LogLevel::INFO));
|
||||
$this->assertEquals(1, $stats->logEntries(LogLevel::DEBUG));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::passwordResets
|
||||
*/
|
||||
public function testPasswordResets()
|
||||
{
|
||||
$this->initDatabase();
|
||||
$this->addUsers();
|
||||
|
||||
(new PasswordReset(['use_id' => 1, 'token' => 'loremIpsum123']))->save();
|
||||
(new PasswordReset(['use_id' => 3, 'token' => '5omeR4nd0mTok3N']))->save();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$this->assertEquals(2, $stats->passwordResets());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some example users
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue