1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::GenericInterface::DebugLog; 10 11use strict; 12use warnings; 13 14use Kernel::System::VariableCheck qw(:all); 15 16our @ObjectDependencies = ( 17 'Kernel::System::Cache', 18 'Kernel::System::DB', 19 'Kernel::System::Log', 20); 21 22=head1 NAME 23 24Kernel::System::GenericInterface::DebugLog - log interface for generic interface 25 26=head1 DESCRIPTION 27 28All log functions. 29 30=head1 PUBLIC INTERFACE 31 32=head2 new() 33 34create a debug log object. Do not use it directly, instead use: 35 36 my $DebugLogObject = $Kernel::OM->Get('Kernel::System::GenericInterface::DebugLog'); 37 38=cut 39 40sub new { 41 my ( $Type, %Param ) = @_; 42 43 # allocate new hash for object 44 my $Self = {}; 45 bless( $Self, $Type ); 46 47 $Self->{CacheType} = 'GenericInterfaceDebugLog'; 48 $Self->{CacheTTL} = 60 * 60 * 24 * 20; 49 50 return $Self; 51} 52 53=head2 LogAdd() 54 55add a communication bit to database 56if we don't already have a communication chain, create it 57 58returns 1 on success or undef on error 59 60 my $Success = $DebugLogObject->LogAdd( 61 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 62 CommunicationType => 'Provider', # 'Provider' or 'Requester' 63 Data => 'additional data' # optional 64 DebugLevel => 'info', # 'debug', 'info', 'notice', 'error' 65 RemoteIP => '192.168.0.1', # optional, must be valid IPv4 or IPv6 address 66 Summary => 'description of log entry', 67 WebserviceID => 1, 68 ); 69 70=cut 71 72sub LogAdd { 73 my ( $Self, %Param ) = @_; 74 75 # check needed params 76 NEEDED: 77 for my $Needed (qw(CommunicationID CommunicationType DebugLevel Summary WebserviceID)) 78 { 79 next NEEDED if IsStringWithData( $Param{$Needed} ); 80 81 $Kernel::OM->Get('Kernel::System::Log')->Log( 82 Priority => 'error', 83 Message => "Need $Needed as a string!", 84 ); 85 return; 86 } 87 88 # param syntax check 89 if ( !IsMD5Sum( $Param{CommunicationID} ) ) { 90 $Kernel::OM->Get('Kernel::System::Log')->Log( 91 Priority => 'error', 92 Message => 'CommunicationID is not an md5sum!', 93 ); 94 return; 95 } 96 if ( $Param{CommunicationType} !~ m{ \A (?: Provider | Requester ) \z }xms ) { 97 $Kernel::OM->Get('Kernel::System::Log')->Log( 98 Priority => 'error', 99 Message => "CommunicationType '$Param{CommunicationType}' is not valid!", 100 ); 101 return; 102 } 103 if ( 104 defined $Param{RemoteIP} && 105 $Param{RemoteIP} ne '' 106 ) 107 { 108 if ( !IsStringWithData( $Param{RemoteIP} ) ) { 109 $Kernel::OM->Get('Kernel::System::Log')->Log( 110 Priority => 'error', 111 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 112 ); 113 return; 114 } 115 if ( !IsIPv4Address( $Param{RemoteIP} ) && !IsIPv6Address( $Param{RemoteIP} ) ) { 116 $Kernel::OM->Get('Kernel::System::Log')->Log( 117 Priority => 'error', 118 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 119 ); 120 return; 121 } 122 } 123 if ( !IsPositiveInteger( $Param{WebserviceID} ) ) { 124 $Kernel::OM->Get('Kernel::System::Log')->Log( 125 Priority => 'error', 126 Message => 'WebserviceID is not a positive integer!', 127 ); 128 return; 129 } 130 KEY: 131 for my $Key (qw(Data DebugLevel Summary)) { 132 next KEY if !defined $Param{$Key}; 133 if ( !IsString( $Param{$Key} ) ) { 134 $Kernel::OM->Get('Kernel::System::Log')->Log( 135 Priority => 'error', 136 Message => "$Key is not a string!", 137 ); 138 return; 139 } 140 } 141 142 # check if we have a communication chain already 143 my $LogData = $Self->LogGet( 144 CommunicationID => $Param{CommunicationID}, 145 ); 146 if ( !IsHashRefWithData($LogData) ) { 147 148 # no entry yet, create one 149 return if !$Self->_LogAddChain( 150 CommunicationID => $Param{CommunicationID}, 151 CommunicationType => $Param{CommunicationType}, 152 RemoteIP => $Param{RemoteIP}, 153 WebserviceID => $Param{WebserviceID}, 154 ); 155 $LogData = $Self->LogGet( 156 CommunicationID => $Param{CommunicationID}, 157 ); 158 } 159 else { 160 161 # match param against existing chain 162 KEY: 163 for my $Key (qw(CommunicationType RemoteIP WebserviceID)) { 164 next KEY if !defined $Param{$Key}; 165 next KEY if $Param{$Key} eq $LogData->{$Key}; 166 167 $Kernel::OM->Get('Kernel::System::Log')->Log( 168 Priority => 'error', 169 Message => "$Key does not match current value for this CommunicationID!", 170 ); 171 return; 172 } 173 } 174 175 # create entry 176 if ( 177 !$Kernel::OM->Get('Kernel::System::DB')->Do( 178 SQL => 179 'INSERT INTO gi_debugger_entry_content' 180 . ' (content, create_time, debug_level, gi_debugger_entry_id, subject)' 181 . ' VALUES (?, current_timestamp, ?, ?, ?)', 182 Bind => [ 183 \$Param{Data}, \$Param{DebugLevel}, \$LogData->{LogID}, \$Param{Summary}, 184 ], 185 ) 186 ) 187 { 188 $Kernel::OM->Get('Kernel::System::Log')->Log( 189 Priority => 'error', 190 Message => 'Could not create debug entry in db!', 191 ); 192 return; 193 } 194 195 return 1; 196} 197 198=head2 LogGet() 199 200get communication chain data 201 202 my $LogData = $DebugLogObject->LogGet( 203 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 204 ); 205 206 $LogData = { 207 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 208 CommunicationType => 'Provider', 209 Created => '2011-02-15 16:47:28', 210 LogID => 1, 211 RemoteIP => '192.168.0.1', # optional 212 WebserviceID => 1, 213 }; 214 215=cut 216 217sub LogGet { 218 my ( $Self, %Param ) = @_; 219 220 # check needed param 221 if ( !IsMD5Sum( $Param{CommunicationID} ) ) { 222 $Kernel::OM->Get('Kernel::System::Log')->Log( 223 Priority => 'error', 224 Message => 'CommunicationID is not an md5sum!', 225 ); 226 return; 227 } 228 229 # check cache 230 my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get( 231 Type => $Self->{CacheType}, 232 Key => 'LogGet::' . $Param{CommunicationID}, 233 ); 234 return $Cache if $Cache; 235 236 # get database object 237 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 238 239 # prepare db request 240 if ( 241 !$DBObject->Prepare( 242 SQL => 243 'SELECT communication_id, communication_type, create_time, id, remote_ip,' 244 . ' webservice_id FROM gi_debugger_entry WHERE communication_id = ?', 245 Bind => [ \$Param{CommunicationID} ], 246 Limit => 1, 247 ) 248 ) 249 { 250 $Kernel::OM->Get('Kernel::System::Log')->Log( 251 Priority => 'error', 252 Message => 'Could not prepare db query!', 253 ); 254 return; 255 } 256 257 # read data 258 my %LogData; 259 while ( my @Row = $DBObject->FetchrowArray() ) { 260 %LogData = ( 261 CommunicationID => $Row[0], 262 CommunicationType => $Row[1], 263 Created => $Row[2], 264 LogID => $Row[3], 265 RemoteIP => $Row[4] || '', 266 WebserviceID => $Row[5], 267 ); 268 } 269 270 return if !%LogData; 271 272 # set cache 273 $Kernel::OM->Get('Kernel::System::Cache')->Set( 274 Type => $Self->{CacheType}, 275 TTL => $Self->{CacheTTL}, 276 Key => 'LogGet::' . $Param{CommunicationID}, 277 Value => \%LogData, 278 ); 279 280 return \%LogData; 281} 282 283=head2 LogGetWithData() 284 285get all individual entries for a communication chain 286 287 my $LogData = $DebugLogObject->LogGetWithData( 288 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 289 ); 290 291 $LogData = { 292 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 293 CommunicationType => 'Provider', 294 Created => '2011-02-15 16:47:28', 295 LogID => 1, 296 RemoteIP => '192.168.0.1', # optional 297 WebserviceID => 1, 298 Data => [ 299 { 300 Created => '2011-02-15 17:00:06', 301 Data => 'some logging specific data or structure', # optional 302 DebugLevel => 'info', 303 Summary => 'a log bit', 304 }, 305 ... 306 ], 307 }; 308 309=cut 310 311sub LogGetWithData { 312 my ( $Self, %Param ) = @_; 313 314 # check needed param 315 if ( !IsMD5Sum( $Param{CommunicationID} ) ) { 316 $Kernel::OM->Get('Kernel::System::Log')->Log( 317 Priority => 'error', 318 Message => 'CommunicationID is not an md5sum!', 319 ); 320 return; 321 } 322 323 # check if we have data for this communication id 324 my $LogData = $Self->LogGet( 325 CommunicationID => $Param{CommunicationID}, 326 ); 327 if ( !IsHashRefWithData($LogData) ) { 328 $Kernel::OM->Get('Kernel::System::Log')->Log( 329 Priority => 'error', 330 Message => 'Could not get communication chain!', 331 ); 332 return; 333 } 334 335 # get database object 336 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 337 338 # prepare db request 339 if ( 340 !$DBObject->Prepare( 341 SQL => 342 'SELECT create_time, content, debug_level, subject' 343 . ' FROM gi_debugger_entry_content WHERE gi_debugger_entry_id = ?' 344 . ' ORDER BY create_time ASC, id ASC', 345 Bind => [ \$LogData->{LogID} ], 346 ) 347 ) 348 { 349 $Kernel::OM->Get('Kernel::System::Log')->Log( 350 Priority => 'error', 351 Message => 'Could not prepare db query!', 352 ); 353 return; 354 } 355 356 # read data 357 my @LogDataEntries; 358 while ( my @Row = $DBObject->FetchrowArray() ) { 359 my %SingleEntry = ( 360 Created => $Row[0], 361 Data => $Row[1] || '', 362 DebugLevel => $Row[2], 363 Summary => $Row[3], 364 ); 365 push @LogDataEntries, \%SingleEntry; 366 } 367 368 $LogData->{Data} = \@LogDataEntries; 369 return $LogData; 370} 371 372=head2 LogDelete() 373 374delete a complete communication chain 375 376returns 1 if successful or undef otherwise 377 378 my $Success = $DebugLogObject->LogDelete( 379 NoErrorIfEmpty => 1, # optional 380 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', # optional 381 WebserviceID => 1, # optional 382 # exactly one id parameter required 383 ); 384 385=cut 386 387sub LogDelete { 388 my ( $Self, %Param ) = @_; 389 390 # check needed params 391 my $CommunicationIDValid = IsMD5Sum( $Param{CommunicationID} ); 392 if ( $Param{CommunicationID} && !$CommunicationIDValid ) { 393 $Kernel::OM->Get('Kernel::System::Log')->Log( 394 Priority => 'error', 395 Message => 'CommunicationID is not an md5sum!', 396 ); 397 return; 398 } 399 my $WebserviceIDValid = IsPositiveInteger( $Param{WebserviceID} ); 400 if ( $Param{WebserviceID} && !$WebserviceIDValid ) { 401 $Kernel::OM->Get('Kernel::System::Log')->Log( 402 Priority => 'error', 403 Message => 'WebserviceID is not a positive integer!', 404 ); 405 return; 406 } 407 if ( 408 ( !$CommunicationIDValid && !$WebserviceIDValid ) 409 || 410 ( $CommunicationIDValid && $WebserviceIDValid ) 411 ) 412 { 413 $Kernel::OM->Get('Kernel::System::Log')->Log( 414 Priority => 'error', 415 Message => 'Need exactly one of CommunicationID or WebserviceID!', 416 ); 417 return; 418 } 419 420 # check if we have data for this param 421 if ($CommunicationIDValid) { 422 my $LogData = $Self->LogGet( 423 CommunicationID => $Param{CommunicationID}, 424 ); 425 if ( !IsHashRefWithData($LogData) ) { 426 return 1 if $Param{NoErrorIfEmpty}; 427 $Kernel::OM->Get('Kernel::System::Log')->Log( 428 Priority => 'error', 429 Message => 'Communication chain does not exist!', 430 ); 431 return; 432 } 433 } 434 else { 435 my $LogData = $Self->LogSearch( 436 Limit => 1, 437 WebserviceID => $Param{WebserviceID}, 438 ); 439 if ( !IsArrayRefWithData($LogData) ) { 440 return 1 if $Param{NoErrorIfEmpty}; 441 $Kernel::OM->Get('Kernel::System::Log')->Log( 442 Priority => 'error', 443 Message => 'Communication chain does not exist!', 444 ); 445 return; 446 } 447 } 448 449 # delete individual entries first 450 my $SQLIndividual = 451 'DELETE FROM gi_debugger_entry_content 452 WHERE gi_debugger_entry_id in( SELECT id FROM gi_debugger_entry '; 453 my @BindIndividual; 454 if ($CommunicationIDValid) { 455 $SQLIndividual .= 'WHERE communication_id = ?'; 456 push @BindIndividual, \$Param{CommunicationID}; 457 } 458 else { 459 $SQLIndividual .= 'WHERE webservice_id = ?'; 460 push @BindIndividual, \$Param{WebserviceID}; 461 } 462 $SQLIndividual .= ' )'; 463 464 # get database object 465 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 466 467 if ( 468 !$DBObject->Do( 469 SQL => $SQLIndividual, 470 Bind => \@BindIndividual, 471 ) 472 ) 473 { 474 $Kernel::OM->Get('Kernel::System::Log')->Log( 475 Priority => 'error', 476 Message => 'Could not remove entries of communication chain in db!', 477 ); 478 return; 479 } 480 481 # delete main entry 482 my $SQLMain = 'DELETE FROM gi_debugger_entry WHERE'; 483 my @BindMain; 484 if ($CommunicationIDValid) { 485 $SQLMain .= ' communication_id = ?'; 486 push @BindMain, \$Param{CommunicationID}; 487 } 488 else { 489 $SQLMain .= ' webservice_id = ?'; 490 push @BindMain, \$Param{WebserviceID}; 491 } 492 if ( 493 !$DBObject->Do( 494 SQL => $SQLMain, 495 Bind => \@BindMain, 496 ) 497 ) 498 { 499 $Kernel::OM->Get('Kernel::System::Log')->Log( 500 Priority => 'error', 501 Message => 'Could not remove communication chain in db!', 502 ); 503 return; 504 } 505 506 # clean cache 507 $Kernel::OM->Get('Kernel::System::Cache')->CleanUp( 508 Type => $Self->{CacheType}, 509 ); 510 511 return 1; 512} 513 514=head2 LogSearch() 515 516search for log chains based on several criteria 517when the parameter 'WithData' is set, the complete communication chains will be returned 518 519 my $LogData = $DebugLogObject->LogSearch( 520 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', # optional 521 CommunicationType => 'Provider', # optional, 'Provider' or 'Requester' 522 CreatedAtOrAfter => '2011-01-01 00:00:00', # optional 523 CreatedAtOrBefore => '2011-12-31 23:59:59', # optional 524 Limit => 1000, # optional, default 100 525 RemoteIP => '192.168.0.1', # optional, must be valid IPv4 or IPv6 address 526 WebserviceID => 1, # optional 527 WithData => 0, # optional 528 Sort => 'ASC', # optional. 'ASC' (default) or 'DESC' 529 ); 530 531 $LogData = [ 532 { 533 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 534 CommunicationType => 'Provider', 535 Created => '2011-02-15 16:47:28', 536 LogID => 1, 537 RemoteIP => '192.168.0.1', # optional 538 WebserviceID => 1, 539 Data => [ # only when 'WithData' is set 540 { 541 Created => '2011-02-15 17:00:06', 542 Data => 'some logging specific data or structure', # optional 543 DebugLevel => 'info', 544 Summary => 'a log bit', 545 }, 546 ... 547 ], 548 }, 549 ... 550 ]; 551 552=cut 553 554sub LogSearch { 555 my ( $Self, %Param ) = @_; 556 557 # param check 558 KEY: 559 for my $Key ( 560 qw(CommunicationID CommunicationType CreatedAtOrAfter CreatedAtOrBefore Limit RemoteIP WebserviceID WithData) 561 ) 562 { 563 next KEY if !defined $Param{$Key}; 564 next KEY if IsStringWithData( $Param{$Key} ); 565 566 $Kernel::OM->Get('Kernel::System::Log')->Log( 567 Priority => 'error', 568 Message => "Need $Key as a string!", 569 ); 570 return; 571 } 572 573 # param syntax check 574 if ( $Param{CommunicationID} && !IsMD5Sum( $Param{CommunicationID} ) ) { 575 $Kernel::OM->Get('Kernel::System::Log')->Log( 576 Priority => 'error', 577 Message => 'CommunicationID is not an md5sum!', 578 ); 579 return; 580 } 581 if ( 582 $Param{CommunicationType} 583 && $Param{CommunicationType} !~ m{ \A (?: Provider | Requester ) \z }xms 584 ) 585 { 586 $Kernel::OM->Get('Kernel::System::Log')->Log( 587 Priority => 'error', 588 Message => "CommunicationType '$Param{CommunicationType}' is not valid!", 589 ); 590 return; 591 } 592 KEY: 593 for my $Key (qw(CreatedAtOrAfter CreatedAtOrBefore)) { 594 next KEY if !$Param{$Key}; 595 next KEY if $Param{$Key} =~ m{ 596 \A \d{4} - \d{2} - \d{2} [ ] \d{2} : \d{2} : \d{2} \z 597 }xms; 598 599 $Kernel::OM->Get('Kernel::System::Log')->Log( 600 Priority => 'error', 601 Message => "$Key '$Param{$Key}' is not valid!", 602 ); 603 return; 604 } 605 if ( $Param{Limit} && !IsPositiveInteger( $Param{Limit} ) ) { 606 $Kernel::OM->Get('Kernel::System::Log')->Log( 607 Priority => 'error', 608 Message => 'Limit is not a positive integer!', 609 ); 610 return; 611 } 612 if ( 613 defined $Param{RemoteIP} && 614 $Param{RemoteIP} ne '' 615 ) 616 { 617 if ( !IsStringWithData( $Param{RemoteIP} ) ) { 618 $Kernel::OM->Get('Kernel::System::Log')->Log( 619 Priority => 'error', 620 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 621 ); 622 return; 623 } 624 if ( !IsIPv4Address( $Param{RemoteIP} ) && !IsIPv6Address( $Param{RemoteIP} ) ) { 625 $Kernel::OM->Get('Kernel::System::Log')->Log( 626 Priority => 'error', 627 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 628 ); 629 return; 630 } 631 } 632 if ( $Param{WebserviceID} && !IsPositiveInteger( $Param{WebserviceID} ) ) { 633 $Kernel::OM->Get('Kernel::System::Log')->Log( 634 Priority => 'error', 635 Message => 'WebserviceID is not a positive integer!', 636 ); 637 return; 638 } 639 if ( $Param{WithData} && $Param{WithData} !~ m{ \A [01] \z }xms ) { 640 $Kernel::OM->Get('Kernel::System::Log')->Log( 641 Priority => 'error', 642 Message => 'WebserviceID is not a positive integer!', 643 ); 644 return; 645 } 646 if ( 647 IsStringWithData( $Param{Sort} ) 648 && $Param{Sort} ne 'ASC' 649 && $Param{Sort} ne 'DESC' 650 ) 651 { 652 $Kernel::OM->Get('Kernel::System::Log')->Log( 653 Priority => 'error', 654 Message => "Sort must be 'DESC' or 'ASC'!", 655 ); 656 return; 657 } 658 659 # prepare db request 660 my $SQL = 661 'SELECT communication_id, communication_type, id, remote_ip, webservice_id, create_time' 662 . ' FROM gi_debugger_entry'; 663 my @Bind = (); 664 my $SQLExt = ''; 665 my %NameToDB = ( 666 CommunicationID => 'communication_id', 667 CommunicationType => 'communication_type', 668 RemoteIP => 'remote_ip', 669 WebserviceID => 'webservice_id', 670 ); 671 672 OPTION: 673 for my $Option (qw(CommunicationID CommunicationType RemoteIP WebserviceID)) { 674 next OPTION if !$Param{$Option}; 675 my $Type = $SQLExt ? 'AND' : 'WHERE'; 676 $SQLExt .= " $Type $NameToDB{$Option} = ?"; 677 push @Bind, \$Param{$Option}; 678 } 679 680 if ( $Param{CreatedAtOrAfter} ) { 681 my $Type = $SQLExt ? 'AND' : 'WHERE'; 682 $SQLExt .= " $Type create_time >= ?"; 683 push @Bind, \$Param{CreatedAtOrAfter}; 684 } 685 686 if ( $Param{CreatedAtOrBefore} ) { 687 my $Type = $SQLExt ? 'AND' : 'WHERE'; 688 $SQLExt .= " $Type create_time <= ?"; 689 push @Bind, \$Param{CreatedAtOrBefore}; 690 } 691 692 my $SQLSort = IsStringWithData( $Param{Sort} ) ? $Param{Sort} : 'ASC'; 693 $SQLExt .= ' ORDER BY create_time ' . $SQLSort; 694 695 # get database object 696 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 697 698 if ( 699 !$DBObject->Prepare( 700 SQL => $SQL . $SQLExt, 701 Bind => \@Bind, 702 Limit => $Param{Limit} || 100, 703 ) 704 ) 705 { 706 $Kernel::OM->Get('Kernel::System::Log')->Log( 707 Priority => 'error', 708 Message => 'Could not prepare db query!', 709 ); 710 return; 711 } 712 713 # read data 714 my @LogEntries; 715 while ( my @Row = $DBObject->FetchrowArray() ) { 716 my %SingleEntry = ( 717 CommunicationID => $Row[0], 718 CommunicationType => $Row[1], 719 LogID => $Row[2], 720 RemoteIP => $Row[3] || '', 721 WebserviceID => $Row[4], 722 Created => $Row[5], 723 ); 724 push @LogEntries, \%SingleEntry; 725 } 726 727 # done if we only need main entries 728 return \@LogEntries if !$Param{WithData}; 729 730 # we need individual entries 731 my @LogEntriesWithData; 732 for my $Entry (@LogEntries) { 733 my $LogData = $Self->LogGetWithData( 734 CommunicationID => $Entry->{CommunicationID}, 735 ); 736 return if !$LogData; 737 push @LogEntriesWithData, $LogData; 738 } 739 740 return \@LogEntriesWithData; 741} 742 743=head2 LogCleanup() 744 745removes all log entries (including content) from a given time and before. 746 747returns 1 if successful or undef otherwise 748 749 my $Success = $DebugLogObject->LogCleanup( 750 CreatedAtOrBefore => '2011-12-31 23:59:59', 751 ); 752 753=cut 754 755sub LogCleanup { 756 my ( $Self, %Param ) = @_; 757 758 if ( !$Param{CreatedAtOrBefore} ) { 759 $Kernel::OM->Get('Kernel::System::Log')->Log( 760 Priority => 'error', 761 Message => "Need CreatedAtOrBefore", 762 ); 763 764 return; 765 } 766 767 if ( $Param{CreatedAtOrBefore} !~ m{ \A \d{4} - \d{2} - \d{2} [ ] \d{2} : \d{2} : \d{2} \z }xms ) { 768 769 $Kernel::OM->Get('Kernel::System::Log')->Log( 770 Priority => 'error', 771 Message => "CreatedAtOrBefore is not valid!", 772 ); 773 return; 774 } 775 776 my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime'); 777 my $Success = $DateTimeObject->Set( String => $Param{CreatedAtOrBefore} ); 778 if ( !$Success ) { 779 780 $Kernel::OM->Get('Kernel::System::Log')->Log( 781 Priority => 'error', 782 Message => "CreatedAtOrBefore is not valid!", 783 ); 784 return; 785 } 786 787 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 788 789 # Get main debug log entries to delete 790 if ( 791 !$DBObject->Prepare( 792 SQL => 'SELECT id FROM gi_debugger_entry WHERE create_time <= ?', 793 Bind => [ \$Param{CreatedAtOrBefore} ], 794 ) 795 ) 796 { 797 $Kernel::OM->Get('Kernel::System::Log')->Log( 798 Priority => 'error', 799 Message => 'Could not prepare db query!', 800 ); 801 return; 802 } 803 my @LogEntryIDs; 804 while ( my @Row = $DBObject->FetchrowArray() ) { 805 push @LogEntryIDs, $Row[0]; 806 } 807 808 return 1 if !@LogEntryIDs; 809 810 my $LogEntryIDsStr = join ',', @LogEntryIDs; 811 812 # Remove debug log entries contents. 813 if ( 814 !$DBObject->Do( 815 SQL => " 816 DELETE FROM gi_debugger_entry_content 817 WHERE gi_debugger_entry_id in( $LogEntryIDsStr )", 818 ) 819 ) 820 { 821 $Kernel::OM->Get('Kernel::System::Log')->Log( 822 Priority => 'error', 823 Message => 'Could not remove entries of communication chains in db!', 824 ); 825 return; 826 } 827 828 # Remove debug log entries. 829 if ( 830 !$DBObject->Do( 831 SQL => " 832 DELETE FROM gi_debugger_entry 833 WHERE id in( $LogEntryIDsStr )", 834 ) 835 ) 836 { 837 $Kernel::OM->Get('Kernel::System::Log')->Log( 838 Priority => 'error', 839 Message => 'Could not remove communication chains in db!', 840 ); 841 return; 842 } 843 844 return 1; 845} 846 847=begin Internal: 848 849=cut 850 851=head2 _LogAddChain() 852 853establish communication chain in database 854 855returns 1 on success or undef on error 856 857 my $Success = $DebugLogObject->_LogAddChain( 858 CommunicationID => '6f1ed002ab5595859014ebf0951522d9', 859 CommunicationType => 'Provider', # 'Provider' or 'Requester' 860 RemoteIP => '192.168.0.1', # optional, must be valid IPv4 or IPv6 address 861 WebserviceID => 1, 862 ); 863 864=cut 865 866sub _LogAddChain { 867 my ( $Self, %Param ) = @_; 868 869 # check needed params 870 NEEDED: 871 for my $Needed (qw(CommunicationID CommunicationType WebserviceID)) { 872 next NEEDED if IsStringWithData( $Param{$Needed} ); 873 874 $Kernel::OM->Get('Kernel::System::Log')->Log( 875 Priority => 'error', 876 Message => "Need $Needed as a string!", 877 ); 878 return; 879 } 880 881 # param syntax check 882 if ( !IsMD5Sum( $Param{CommunicationID} ) ) { 883 $Kernel::OM->Get('Kernel::System::Log')->Log( 884 Priority => 'error', 885 Message => 'CommunicationID is not an md5sum!', 886 ); 887 return; 888 } 889 if ( $Param{CommunicationType} !~ m{ \A (?: Provider | Requester ) \z }xms ) { 890 $Kernel::OM->Get('Kernel::System::Log')->Log( 891 Priority => 'error', 892 Message => "CommunicationType '$Param{CommunicationType}' is not valid!", 893 ); 894 return; 895 } 896 if ( 897 defined $Param{RemoteIP} && 898 $Param{RemoteIP} ne '' 899 ) 900 { 901 if ( !IsStringWithData( $Param{RemoteIP} ) ) { 902 $Kernel::OM->Get('Kernel::System::Log')->Log( 903 Priority => 'error', 904 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 905 ); 906 return; 907 } 908 if ( !IsIPv4Address( $Param{RemoteIP} ) && !IsIPv6Address( $Param{RemoteIP} ) ) { 909 $Kernel::OM->Get('Kernel::System::Log')->Log( 910 Priority => 'error', 911 Message => "RemoteIP '$Param{RemoteIP}' is not a valid IPv4 or IPv6 address!", 912 ); 913 return; 914 } 915 } 916 if ( !IsPositiveInteger( $Param{WebserviceID} ) ) { 917 $Kernel::OM->Get('Kernel::System::Log')->Log( 918 Priority => 'error', 919 Message => 'WebserviceID is not a positive integer!', 920 ); 921 return; 922 } 923 924 if ( 925 !$Kernel::OM->Get('Kernel::System::DB')->Do( 926 SQL => 927 'INSERT INTO gi_debugger_entry' 928 . ' (communication_id, communication_type, create_time, remote_ip,' 929 . ' webservice_id)' 930 . ' VALUES (?, ?, current_timestamp, ?, ?)', 931 Bind => [ 932 \$Param{CommunicationID}, \$Param{CommunicationType}, 933 \$Param{RemoteIP}, \$Param{WebserviceID}, 934 ], 935 ) 936 ) 937 { 938 $Kernel::OM->Get('Kernel::System::Log')->Log( 939 Priority => 'error', 940 Message => 'Could not create debug entry chain in db!', 941 ); 942 return; 943 } 944 945 return 1; 946} 947 9481; 949 950=end Internal: 951 952=head1 TERMS AND CONDITIONS 953 954This software is part of the OTRS project (L<https://otrs.org/>). 955 956This software comes with ABSOLUTELY NO WARRANTY. For details, see 957the enclosed file COPYING for license information (GPL). If you 958did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>. 959 960=cut 961