196 lines
5.8 KiB
Perl
196 lines
5.8 KiB
Perl
# --
|
|
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
|
# --
|
|
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
|
# the enclosed file COPYING for license information (GPL). If you
|
|
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
|
# --
|
|
|
|
package Kernel::System::SupportDataCollector::PluginAsynchronous::OTRS::ConcurrentUsers;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use parent qw(Kernel::System::SupportDataCollector::PluginAsynchronous);
|
|
|
|
use Kernel::Language qw(Translatable);
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::Config',
|
|
'Kernel::System::AuthSession',
|
|
'Kernel::System::SystemData',
|
|
'Kernel::System::DateTime',
|
|
);
|
|
|
|
sub GetDisplayPath {
|
|
return
|
|
'OTRS@Table:TimeStamp,UserSessionUnique|Unique agents,UserSession|Agent sessions,CustomerSessionUnique|Unique customers,CustomerSession|Customer sessions';
|
|
}
|
|
|
|
sub Run {
|
|
my $Self = shift;
|
|
|
|
my $ConcurrentUsers = $Self->_GetAsynchronousData();
|
|
|
|
# the table details data
|
|
$Self->AddResultInformation(
|
|
Label => Translatable('Concurrent Users Details'),
|
|
Value => $ConcurrentUsers || [],
|
|
);
|
|
|
|
# get the full display path
|
|
my $DisplayPathFull = $Self->GetDisplayPath();
|
|
|
|
# get the display path, display type and additional information for the output
|
|
my ( $DisplayPath, $DisplayType, $DisplayAdditional ) = split( m{[\@\:]}, $DisplayPathFull // '' );
|
|
|
|
# get the table columns (possible with label)
|
|
my @TableColumns = split( m{,}, $DisplayAdditional // '' );
|
|
|
|
COLUMN:
|
|
for my $Column (@TableColumns) {
|
|
|
|
next COLUMN if !$Column;
|
|
|
|
# get the identifier and label
|
|
my ( $Identifier, $Label ) = split( m{\|}, $Column );
|
|
|
|
# set the identifier as default label
|
|
$Label ||= $Identifier;
|
|
|
|
next COLUMN if $Identifier eq 'TimeStamp';
|
|
|
|
my $MaxValue = 0;
|
|
|
|
ENTRY:
|
|
for my $Entry ( @{$ConcurrentUsers} ) {
|
|
|
|
next ENTRY if !$Entry->{$Identifier};
|
|
next ENTRY if $Entry->{$Identifier} && $Entry->{$Identifier} <= $MaxValue;
|
|
|
|
$MaxValue = $Entry->{$Identifier} || 0;
|
|
}
|
|
|
|
$Self->AddResultInformation(
|
|
DisplayPath => Translatable('OTRS') . '/' . Translatable('Concurrent Users'),
|
|
Identifier => $Identifier,
|
|
Label => "Max. $Label",
|
|
Value => $MaxValue,
|
|
);
|
|
}
|
|
|
|
return $Self->GetResults();
|
|
}
|
|
|
|
sub RunAsynchronous {
|
|
my $Self = shift;
|
|
|
|
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
my $SystemTimeNow = $DateTimeObject->ToEpoch();
|
|
|
|
$DateTimeObject->Add( Hours => 1 );
|
|
|
|
# Get the time values and use only the full hour.
|
|
my $DateTimeValues = $DateTimeObject->Get();
|
|
$DateTimeObject->Set(
|
|
Year => $DateTimeValues->{Year},
|
|
Month => $DateTimeValues->{Month},
|
|
Day => $DateTimeValues->{Day},
|
|
Hour => $DateTimeValues->{Hour},
|
|
Minute => 0,
|
|
Second => 0,
|
|
);
|
|
my $TimeStamp = $DateTimeObject->ToString();
|
|
|
|
my $AsynchronousData = $Self->_GetAsynchronousData();
|
|
|
|
my $CurrentHourPosition;
|
|
|
|
if ( IsArrayRefWithData($AsynchronousData) ) {
|
|
|
|
# already existing entry counter
|
|
my $AsynchronousDataCount = scalar @{$AsynchronousData} - 1;
|
|
|
|
# check if for the current hour already a value exists
|
|
COUNTER:
|
|
for my $Counter ( 0 .. $AsynchronousDataCount ) {
|
|
|
|
next COUNTER
|
|
if $AsynchronousData->[$Counter]->{TimeStamp}
|
|
&& $AsynchronousData->[$Counter]->{TimeStamp} ne $TimeStamp;
|
|
|
|
$CurrentHourPosition = $Counter;
|
|
|
|
last COUNTER;
|
|
}
|
|
|
|
# set the check timestamp to one week ago
|
|
$DateTimeObject->Subtract( Days => 7 );
|
|
my $CheckTimeStamp = $DateTimeObject->ToString();
|
|
|
|
# remove all entries older than one week
|
|
@{$AsynchronousData} = grep { $_->{TimeStamp} && $_->{TimeStamp} ge $CheckTimeStamp } @{$AsynchronousData};
|
|
}
|
|
|
|
# get AuthSession object
|
|
my $AuthSessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');
|
|
|
|
# delete the old session ids
|
|
my @Expired = $AuthSessionObject->GetExpiredSessionIDs();
|
|
for ( 0 .. 1 ) {
|
|
for my $SessionID ( @{ $Expired[$_] } ) {
|
|
$AuthSessionObject->RemoveSessionID( SessionID => $SessionID );
|
|
}
|
|
}
|
|
|
|
# to count the agents and customer user sessions
|
|
my %CountConcurrentUser = (
|
|
TimeStamp => $TimeStamp,
|
|
UserSessionUnique => 0,
|
|
UserSession => 0,
|
|
CustomerSession => 0,
|
|
CustomerSessionUnique => 0,
|
|
);
|
|
|
|
for my $UserType (qw(User Customer)) {
|
|
|
|
my %ActiveSessions = $AuthSessionObject->GetActiveSessions(
|
|
UserType => $UserType,
|
|
);
|
|
|
|
$CountConcurrentUser{ $UserType . 'Session' } = $ActiveSessions{Total};
|
|
$CountConcurrentUser{ $UserType . 'SessionUnique' } = scalar keys %{ $ActiveSessions{PerUser} };
|
|
}
|
|
|
|
# update the concurrent user counter, if a higher value for the current hour exists
|
|
if ( defined $CurrentHourPosition ) {
|
|
|
|
my $ChangedConcurrentUserCounter;
|
|
|
|
IDENTIFIER:
|
|
for my $Identifier (qw(UserSessionUnique UserSession CustomerSession CustomerSessionUnique)) {
|
|
|
|
next IDENTIFIER
|
|
if $AsynchronousData->[$CurrentHourPosition]->{$Identifier} >= $CountConcurrentUser{$Identifier};
|
|
|
|
$AsynchronousData->[$CurrentHourPosition]->{$Identifier} = $CountConcurrentUser{$Identifier};
|
|
|
|
$ChangedConcurrentUserCounter = 1;
|
|
}
|
|
|
|
return 1 if !$ChangedConcurrentUserCounter;
|
|
}
|
|
else {
|
|
push @{$AsynchronousData}, \%CountConcurrentUser;
|
|
}
|
|
|
|
$Self->_StoreAsynchronousData(
|
|
Data => $AsynchronousData,
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
1;
|