Преглед изворни кода

The log has been rewritten to Log::Log4perl. Optimized the survey for snmp

Roman Dmitriev пре 3 недеља
родитељ
комит
9a7960c246
47 измењених фајлова са 654 додато и 408 уклоњено
  1. 4 4
      install-eye.sh
  2. 1 0
      scripts/check_dhcp_pool.pl
  3. 1 0
      scripts/dhcp-log.pl
  4. 1 0
      scripts/eye-statd.pl
  5. 1 0
      scripts/eyelib/cmd.pm
  6. 1 0
      scripts/eyelib/common.pm
  7. 106 81
      scripts/eyelib/config.pm
  8. 43 85
      scripts/eyelib/database.pm
  9. 200 0
      scripts/eyelib/logconfig.pm
  10. 1 101
      scripts/eyelib/main.pm
  11. 1 0
      scripts/eyelib/nagios.pm
  12. 1 0
      scripts/eyelib/net_utils.pm
  13. 1 0
      scripts/eyelib/rest_api.pm
  14. 250 104
      scripts/eyelib/snmp.pm
  15. 3 0
      scripts/fetch_new_arp.pl
  16. 1 25
      scripts/garbage.pl
  17. 1 0
      scripts/gen_nagios_config.pl
  18. 1 0
      scripts/hmonitor.pl
  19. 1 0
      scripts/print-dnsmasq.pl
  20. 1 0
      scripts/restart_port_snmp.pl
  21. 1 0
      scripts/stat-sync.pl
  22. 1 0
      scripts/sync_iptables.pl
  23. 1 0
      scripts/sync_mikrotik.pl
  24. 1 0
      scripts/sync_mikrotik_poe_monitor.pl
  25. 1 0
      scripts/syslog-stat.pl
  26. 1 0
      scripts/updates/2-8-0/after_sql.pl
  27. 1 0
      scripts/updates/db-patch-mysql-utf8.pl
  28. 1 0
      scripts/updates/upgrade.pl
  29. 1 0
      scripts/utils/backupcfg.pl
  30. 1 0
      scripts/utils/bind/print-dns-zones.pl
  31. 5 4
      scripts/utils/import-system-dev.pl
  32. 1 0
      scripts/utils/import/import_auth.pl
  33. 1 0
      scripts/utils/mac-oids/update-mac-vendors.pl
  34. 1 0
      scripts/utils/oxidized/print_devices_oxi.pl
  35. 1 0
      scripts/utils/parse_flow.pl
  36. 1 0
      scripts/utils/print-ou-ip.pl
  37. 1 0
      scripts/utils/print_cacti_create.pl
  38. 1 0
      scripts/utils/print_cacti_hosts.pl
  39. 1 0
      scripts/utils/print_devices.pl
  40. 1 0
      scripts/utils/radius/print_huntgroups.pl
  41. 1 0
      scripts/utils/reaply_rules.pl
  42. 1 0
      scripts/utils/scan_ipcam.pl
  43. 1 0
      scripts/utils/set_dns_record.pl
  44. 1 0
      scripts/utils/set_port_descr.pl
  45. 4 4
      scripts/utils/trap_restart.pl
  46. 1 0
      scripts/utils/win32/print-dhcpd-netsh.pl
  47. 1 0
      scripts/utils/win32/sync-dhcpd-netsh.pl

+ 4 - 4
install-eye.sh

@@ -342,7 +342,7 @@ install_deps_altlinux() {
             perl-Net-OpenSSH perl-File-Tail perl-Tie-File \
             perl-Net-OpenSSH perl-File-Tail perl-Tie-File \
             perl-Crypt-Rijndael perl-Crypt-CBC perl-CryptX perl-Crypt-DES \
             perl-Crypt-Rijndael perl-Crypt-CBC perl-CryptX perl-Crypt-DES \
             perl-File-Path-Tiny perl-Expect perl-Proc-ProcessTable \
             perl-File-Path-Tiny perl-Expect perl-Proc-ProcessTable \
-            perl-Text-CSV \
+            perl-Text-CSV perl-Log-Log4perl \
             perl-DBD-Pg perl-DBD-mysql
             perl-DBD-Pg perl-DBD-mysql
     fi
     fi
 
 
@@ -402,7 +402,7 @@ install_deps_debian() {
             libcrypt-rijndael-perl libcrypt-cbc-perl libcryptx-perl \
             libcrypt-rijndael-perl libcrypt-cbc-perl libcryptx-perl \
             libcrypt-des-perl libfile-path-tiny-perl libexpect-perl \
             libcrypt-des-perl libfile-path-tiny-perl libexpect-perl \
             libtext-csv-perl \
             libtext-csv-perl \
-            libdbd-pg-perl libdbd-mysql-perl
+            libdbd-pg-perl libdbd-mysql-perl liblog-log4perl-perl
     fi
     fi
 
 
     # === Дополнительно (если нужно) ===
     # === Дополнительно (если нужно) ===
@@ -622,7 +622,7 @@ upgrade_source_code() {
     if [ -d "docs" ]; then
     if [ -d "docs" ]; then
         print_info "Updating documentation..."
         print_info "Updating documentation..."
         mkdir -p /opt/Eye/docs
         mkdir -p /opt/Eye/docs
-        rsync -a docs/ /opt/Eye/docs/
+        rsync -ar docs/ /opt/Eye/docs/
         chown -R eye:eye /opt/Eye/docs
         chown -R eye:eye /opt/Eye/docs
     fi
     fi
 
 
@@ -642,7 +642,7 @@ upgrade_source_code() {
         print_info "Updating backend scripts..."
         print_info "Updating backend scripts..."
         mkdir -p /opt/Eye/scripts/{cfg,log}
         mkdir -p /opt/Eye/scripts/{cfg,log}
         rsync -a --exclude cfg/ scripts/  /opt/Eye/scripts/
         rsync -a --exclude cfg/ scripts/  /opt/Eye/scripts/
-        rsync -ar --exclude scripts/eyelib/   /opt/Eye/scripts/eyelib/
+        rsync -ar scripts/eyelib/   /opt/Eye/scripts/eyelib/
         # Обновляем только если каталог уже установлен
         # Обновляем только если каталог уже установлен
         [[ -d /opt/Eye/scripts/updates ]] && rsync -ar scripts/updates/ /opt/Eye/scripts/updates/
         [[ -d /opt/Eye/scripts/updates ]] && rsync -ar scripts/updates/ /opt/Eye/scripts/updates/
         [[ -d /opt/Eye/scripts/utils   ]] && rsync -ar scripts/utils/   /opt/Eye/scripts/utils/
         [[ -d /opt/Eye/scripts/utils   ]] && rsync -ar scripts/utils/   /opt/Eye/scripts/utils/

+ 1 - 0
scripts/check_dhcp_pool.pl

@@ -25,6 +25,7 @@ use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
+use eyelib::logconfig;
 use File::Basename;
 use File::Basename;
 use File::Path;
 use File::Path;
 
 

+ 1 - 0
scripts/dhcp-log.pl

@@ -22,6 +22,7 @@ use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
+use eyelib::logconfig;
 use strict;
 use strict;
 use Getopt::Long;
 use Getopt::Long;
 use Proc::Daemon;
 use Proc::Daemon;

+ 1 - 0
scripts/eye-statd.pl

@@ -19,6 +19,7 @@ use Date::Parse;
 use DateTime;
 use DateTime;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 1 - 0
scripts/eyelib/cmd.pm

@@ -15,6 +15,7 @@ use vars qw(@EXPORT @ISA);
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use Net::Telnet;
 use Net::Telnet;
 use Net::OpenSSH;
 use Net::OpenSSH;
 use Expect;
 use Expect;

+ 1 - 0
scripts/eyelib/common.pm

@@ -18,6 +18,7 @@ use Net::Patricia;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use DateTime;
 use DateTime;
 use DateTime::Format::Strptime;
 use DateTime::Format::Strptime;
 use POSIX qw(mktime ctime strftime);
 use POSIX qw(mktime ctime strftime);

+ 106 - 81
scripts/eyelib/config.pm

@@ -27,93 +27,104 @@ use constant {
 use constant NOTIFY_ALL => NOTIFY_CREATE | NOTIFY_UPDATE | NOTIFY_DELETE; # 0111
 use constant NOTIFY_ALL => NOTIFY_CREATE | NOTIFY_UPDATE | NOTIFY_DELETE; # 0111
 
 
 @ISA = qw(Exporter);
 @ISA = qw(Exporter);
+
 @EXPORT = qw(
 @EXPORT = qw(
-$HOME_DIR
-@FN
-$MY_NAME
-$SPID
-$LOG_DIR
-$LOG_COMMON
-$LOG
-$LOG_ERR
-$LOG_DEBUG
-$DHCPD_CONF
-$BEGIN_STR
-$END_STR
-$WARN_MSG
-$WAIT_TIME
-$MIN_SLEEP
-$MAX_SLEEP
+$add_unknown_user
 $admin_email
 $admin_email
-$sender_email
-$send_email
-$HOSTNAME
-$debug
-$log_enable
-$log_level
-$W_INFO
-$W_ERROR
-$W_DEBUG
+$all_networks
+$BEGIN_STR
+$connections_history
+$cpu_count
+$dbh
 $DBHOST
 $DBHOST
 $DBNAME
 $DBNAME
-$DBUSER
 $DBPASS
 $DBPASS
+$DBUSER
+$debug
+$default_hotspot_ou_id
+$default_user_ou_id
+$def_timeout
+$DHCPD_CONF
+$dhcp_pool
+$dhcp_server
+$dns_server
 $domain_auth
 $domain_auth
-$winexe
+$domain_name
+$END_STR
 $fping
 $fping
-$log_owner_user
+$free_networks
+$history
+$history_dhcp
+$history_log_day
+$history_syslog_day
+$history_trafstat_day
+$HOME_DIR
+$HOSTNAME
+$hotspot_networks
+$KB
+$last_refresh_config
+$L_DEBUG
+$L_ERROR
+$L_INFO
+$LOG_DIR
+$log_enable
+$LOG_FILE
+$log_file_mode
+$log_level
 $log_owner_group
 $log_owner_group
-$use_smsd
-$smsaero_wait
-$smsd_group
-$smsd_user
-$def_timeout
+$log_owner_user
+$L_VERBOSE
+$L_WARNING
+$MAX_SLEEP
+$MIN_SLEEP
+$MY_NAME
+$office_networks
+$org_name
 $parallel_process_count
 $parallel_process_count
-$save_detail
-$add_unknown_user
 $router_ip
 $router_ip
-$dns_server
-$dhcp_server
-$snmp_default_version
-$snmp_default_community
-$KB
-$office_networks
-$hotspot_networks
-$all_networks
-@office_network_list
-@hotspot_network_list
-@all_network_list
-$dhcp_pool
-$history
-$history_dhcp
 $router_login
 $router_login
 $router_password
 $router_password
 $router_port
 $router_port
-$org_name
-$domain_name
-$connections_history
-$dbh
+$save_detail
+$send_email
+$sender_email
+$snmp_default_community
+$snmp_default_version
+$SPID
+$tftp_dir
+$tftp_server
 $urgent_sync
 $urgent_sync
-$default_user_ou_id
-$default_hotspot_ou_id
+$vpn_networks;
+$WAIT_TIME
+$WARN_MSG
+
+$W_DEBUG
+$W_ERROR
+$W_WARN
+$W_INFO
+
+$winexe
+%config_ref
+@FN
+@all_network_list
+@free_network_list
+@hotspot_network_list
+@office_network_list
+@vpn_network_list
+@subnets
+%switch_auth
 $ignore_hotspot_dhcp_log
 $ignore_hotspot_dhcp_log
 $ignore_update_dhcp_event
 $ignore_update_dhcp_event
 $update_hostname_from_dhcp
 $update_hostname_from_dhcp
-@subnets
-%subnets_ref
-$history_log_day
-$history_syslog_day
-$history_trafstat_day
+
+$office_networks
 $free_networks
 $free_networks
 $vpn_networks
 $vpn_networks
-@free_network_list
-@vpn_network_list
-%config_ref
-%switch_auth
-$last_refresh_config
-$tftp_dir
-$tftp_server
-$cpu_count
+$hotspot_networks
+$all_networks
+
+%subnets_ref
+
 NOTIFY_NONE
 NOTIFY_NONE
 NOTIFY_CREATE
 NOTIFY_CREATE
 NOTIFY_UPDATE
 NOTIFY_UPDATE
@@ -179,11 +190,7 @@ our $SPID=$config_ref{pid_file};
 
 
 #iptables log
 #iptables log
 our $LOG_DIR            = $config_ref{log_dir};
 our $LOG_DIR            = $config_ref{log_dir};
-our $LOG_COMMON         = "$LOG_DIR/$FN[-1].log";
-
-our $LOG                = $LOG_COMMON;
-our $LOG_ERR            = $LOG_COMMON;
-our $LOG_DEBUG          = $LOG_COMMON;
+our $LOG_FILE           = "$LOG_DIR/$FN[-1].log";
 
 
 our $DHCPD_CONF         = $Config->{_}->{dhcpd_conf} || "/etc/dnsmasq.d";
 our $DHCPD_CONF         = $Config->{_}->{dhcpd_conf} || "/etc/dnsmasq.d";
 
 
@@ -205,16 +212,21 @@ my $HOSTNAME1=`hostname`;
 chomp($HOSTNAME1);
 chomp($HOSTNAME1);
 our $HOSTNAME=$HOSTNAME1;
 our $HOSTNAME=$HOSTNAME1;
 
 
-### debug
-our $debug=0;
-
-our $log_enable = 1;
+our $debug      = 0;        # Включить отладочные сообщения
+our $log_enable = 1;        # Глобальный выключатель логов
+our $log_level  = 2;        # Порог: 0=ERROR, 1=WARNING, 2=INFO, 3=VERBOSE, 255=DEBUG
 
 
-our $log_level = 2;
+# === Константы (для обратной совместимости) ===
+our $W_ERROR = 0;
+our $W_WARN  = 1;
+our $W_INFO  = 2;
+our $W_DEBUG = 255;
 
 
-our $W_INFO = 0;
-our $W_ERROR = 1;
-our $W_DEBUG = 2;
+our $L_ERROR   = 0;
+our $L_WARNING = 1;
+our $L_INFO    = 2;
+our $L_VERBOSE = 3;
+our $L_DEBUG   = 255;
 
 
 our $DBHOST 		= $config_ref{DBHOST};
 our $DBHOST 		= $config_ref{DBHOST};
 our $DBNAME 		= $config_ref{DBNAME};
 our $DBNAME 		= $config_ref{DBNAME};
@@ -233,6 +245,7 @@ our $history_trafstat_day;
 
 
 our $log_owner_user	= $config_ref{log_owner_user};
 our $log_owner_user	= $config_ref{log_owner_user};
 our $log_owner_group	= $config_ref{log_owner_group};
 our $log_owner_group	= $config_ref{log_owner_group};
+our $log_file_mode      = '0660';
 
 
 ################################################################
 ################################################################
 
 
@@ -277,6 +290,18 @@ our $urgent_sync = 0;
 our $tftp_dir=$Config->{_}->{tftp_dir} || '/var/lib/tftpboot';
 our $tftp_dir=$Config->{_}->{tftp_dir} || '/var/lib/tftpboot';
 our $tftp_server=$Config->{_}->{tftp_server} || '';
 our $tftp_server=$Config->{_}->{tftp_server} || '';
 
 
+our $ignore_hotspot_dhcp_log;
+our $ignore_update_dhcp_event;
+our $update_hostname_from_dhcp;
+
+our $office_networks;
+our $free_networks;
+our $vpn_networks;
+our $hotspot_networks;
+our $all_networks;
+
+our %subnets_ref;
+
 our $last_refresh_config = time();
 our $last_refresh_config = time();
 
 
 our %switch_auth = (
 our %switch_auth = (

+ 43 - 85
scripts/eyelib/database.pm

@@ -20,9 +20,6 @@ package eyelib::database;
 #}
 #}
 #$db->{AutoCommit} = 1;
 #$db->{AutoCommit} = 1;
 
 
-use warnings FATAL => 'all';
-use feature ':5.20';
-
 use utf8;
 use utf8;
 use open ":encoding(utf8)";
 use open ":encoding(utf8)";
 use strict;
 use strict;
@@ -35,6 +32,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use Net::Patricia;
 use Net::Patricia;
 use eyelib::net_utils;
 use eyelib::net_utils;
+use eyelib::logconfig;
 use Data::Dumper;
 use Data::Dumper;
 use DateTime;
 use DateTime;
 use POSIX qw(mktime ctime strftime);
 use POSIX qw(mktime ctime strftime);
@@ -98,12 +96,6 @@ clean_variables
 build_db_schema
 build_db_schema
 
 
 $add_rules
 $add_rules
-$L_WARNING
-$L_INFO
-$L_DEBUG
-$L_ERROR
-$L_VERBOSE
-
 %db_schema
 %db_schema
 );
 );
 
 
@@ -114,12 +106,6 @@ BEGIN
 
 
 our $add_rules;
 our $add_rules;
 
 
-our $L_ERROR = 0;
-our $L_WARNING = 1;
-our $L_INFO = 2;
-our $L_VERBOSE = 3;
-our $L_DEBUG = 255;
-
 our %acl_fields = (
 our %acl_fields = (
     'ip' => '1',
     'ip' => '1',
     'ip_int' => '1',
     'ip_int' => '1',
@@ -1068,78 +1054,49 @@ sub reconnect_db {
 #---------------------------------------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------------------------------------
 
 
 sub write_db_log {
 sub write_db_log {
-my $db=shift;
-my $msg=shift;
-my $level = shift || $L_VERBOSE;
-my $auth_id = shift || 0;
-return if (!$db);
-return if (!$msg);
-$msg=~s/[\'\"]//g;
-my $db_log = 0;
-
-# Переподключение
-unless (reconnect_db(\$db)) {
-log_error("No database connection available");
-$db_log = 0;
-}
-
-if ($level eq $L_ERROR and $log_level >= $L_ERROR) { log_error($msg); $db_log = 1; }
-if ($level eq $L_WARNING and $log_level >= $L_WARNING) { log_warning($msg); $db_log = 1; }
-if ($level eq $L_INFO and $log_level >= $L_INFO) { log_info($msg); $db_log = 1; }
-if ($level eq $L_VERBOSE and $log_level >= $L_VERBOSE) { log_verbose($msg); $db_log = 1; }
-if ($level eq $L_DEBUG and $log_level >= $L_DEBUG) { log_debug($msg); return; }
-
-if ($db_log) {
-#my $new_id = do_sql($dbh, 'INSERT INTO user_list (login) VALUES (?)', 'Ivan');
-do_sql($db,'INSERT INTO worklog(customer,message,level,auth_id,ip) VALUES( ?, ?, ?, ?, ?)',$MY_NAME,$msg,$level,$auth_id,$config_ref{self_ip});
-}
+    my ($db, $msg, $level, $auth_id) = @_;
+    $level //= $L_VERBOSE;
+    $auth_id //= 0;
+    return unless $log_enable && $msg && $db;
+    return unless $log_level >= $level;
+    my $method = {
+        $L_ERROR   => 'error',
+        $L_WARNING => 'warn',
+        $L_INFO    => 'info',
+        $L_VERBOSE => 'info',
+        $L_DEBUG   => 'debug',
+    }->{$level} || 'info';
+    if ($level == $L_DEBUG) {
+            return unless $debug;
+            log_debug($msg);
+        } else {
+            for my $line (split /\n/, $msg) {
+            next unless length $line;
+            get_logger()->$method($line);
+            }
+        }
+    eval {
+        reconnect_db(\$db) if defined &reconnect_db;
+        return unless $db && $db->ping;
+        do_sql($db,
+            'INSERT INTO worklog (customer, message, level, auth_id, ip) VALUES (?, ?, ?, ?, ?)',
+            $MY_NAME // 'unknown',
+            $msg,
+            $level,
+            $auth_id // 0,
+            $config_ref{self_ip} // '0.0.0.0'
+        );
+    };
+    warn "write_db_log failed: $@" if $@ && $debug;
 }
 }
 
 
-#---------------------------------------------------------------------------------------------------------------
-
+sub db_log_error   { write_db_log($_[0], $_[1], $L_ERROR,   $_[2]); }
+sub db_log_info    { write_db_log($_[0], $_[1], $L_INFO,    $_[2]); }
+sub db_log_verbose { write_db_log($_[0], $_[1], $L_VERBOSE, $_[2]); }
+sub db_log_warning { write_db_log($_[0], $_[1], $L_WARNING, $_[2]); }
 sub db_log_debug {
 sub db_log_debug {
-my $db = shift;
-my $msg = shift;
-my $id = shift;
-if ($debug) { log_debug($msg); }
-}
-
-#---------------------------------------------------------------------------------------------------------------
-
-sub db_log_error {
-my $db = shift;
-my $msg = shift;
-if ($log_level >= $L_ERROR) {
-sendEmail("ERROR! ".get_first_line($msg),$msg,1);
-write_db_log($db,$msg,$L_ERROR);
-}
-}
-
-#---------------------------------------------------------------------------------------------------------------
-
-sub db_log_info {
-my $db = shift;
-my $msg = shift;
-my $id = shift;
-if ($log_level >= $L_INFO) { write_db_log($db,$msg,$L_INFO,$id); }
-}
-
-#---------------------------------------------------------------------------------------------------------------
-
-sub db_log_verbose {
-my $db = shift;
-my $msg = shift;
-my $id = shift;
-if ($log_level >= $L_VERBOSE) { write_db_log($db,$msg,$L_VERBOSE,$id); }
-}
-
-#---------------------------------------------------------------------------------------------------------------
-
-sub db_log_warning {
-my $db = shift;
-my $msg = shift;
-my $id = shift;
-if ($log_level >= $L_WARNING) { write_db_log($db,$msg,$L_WARNING,$id); }
+    return unless $debug;
+    log_debug($_[1]);
 }
 }
 
 
 #---------------------------------------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------------------------------------
@@ -1943,7 +1900,7 @@ $debug=get_option($db,34);
 
 
 #log level
 #log level
 $log_level = get_option($db,53);
 $log_level = get_option($db,53);
-if ($debug) { $log_level = 255; }
+if ($debug) { $log_level = $L_DEBUG; }
 
 
 #urgent sync access
 #urgent sync access
 $urgent_sync=get_option($db,50);
 $urgent_sync=get_option($db,50);
@@ -2010,6 +1967,7 @@ foreach my $net (@subnets) {
     push(@all_network_list,$net->{subnet});
     push(@all_network_list,$net->{subnet});
     $all_networks->add_string($net->{subnet},$net);
     $all_networks->add_string($net->{subnet},$net);
     }
     }
+set_log_level($log_level);
 }
 }
 
 
 #---------------------------------------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------------------------------------

+ 200 - 0
scripts/eyelib/logconfig.pm

@@ -0,0 +1,200 @@
+package eyelib::logconfig;
+
+use utf8;
+use open ":encoding(utf8)";
+use strict;
+use English;
+use FindBin '$Bin';
+use lib "/opt/Eye/scripts";
+use eyelib::config;
+use Data::Dumper;
+use Log::Log4perl;
+use Fcntl qw(:mode);
+use base 'Exporter';
+use vars qw(@EXPORT @ISA);
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+log_init
+set_log_permissions
+get_logger
+log_info
+log_error
+log_warning
+log_verbose
+log_session
+set_log_level
+log_debug
+log_die
+wrlog
+);
+
+BEGIN
+{
+
+# === Инициализация ===
+sub log_init {
+    my ($logfile) = @_;
+    $LOG_FILE = $logfile if $logfile;
+
+    my $conf = <<"LOG4PERL";
+log4perl.rootLogger = DEBUG, MainLog
+
+log4perl.appender.MainLog = Log::Log4perl::Appender::File
+log4perl.appender.MainLog.filename = $LOG_FILE
+log4perl.appender.MainLog.mode = append
+log4perl.appender.MainLog.umask = 0022
+log4perl.appender.MainLog.utf8 = 1
+log4perl.appender.MainLog.layout = Log::Log4perl::Layout::PatternLayout
+log4perl.appender.MainLog.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [%p] [PID:%P] %m%n
+log4perl.appender.MainLog.recreate = 1
+log4perl.appender.MainLog.Threshold = DEBUG
+LOG4PERL
+
+    Log::Log4perl::init(\$conf);
+    # === Устанавливаем права ПОСЛЕ создания файла ===
+    _set_log_file_permissions();
+    if (!$log_enable) {
+        Log::Log4perl->get_logger()->level($Log::Log4perl::OFF);
+    }
+}
+
+# === Установка прав и владельца ===
+sub _set_log_file_permissions {
+    return unless -e $LOG_FILE;  # Файл должен существовать
+    # Если не root — проверяем, что мы владелец
+    if ($< != 0) {
+        my $stat = stat($LOG_FILE);
+        my $file_uid = (stat($LOG_FILE))[4];
+        if ($file_uid != $<) {
+            warn "WARNING: Cannot change ownership of $LOG_FILE (not running as root)\n";
+            return;
+        }
+    }
+    # Владелец и группа
+    my $uid = getpwnam($log_owner_user);
+    my $gid = getgrnam($log_owner_group);
+    # Fallback на root если пользователь не найден
+    if (!defined $uid) {
+        warn "WARNING: User '$log_owner_user' not found, using current UID\n";
+        $uid = $<;
+    }
+    if (!defined $gid) {
+        warn "WARNING: Group '$log_owner_group' not found, using current GID\n";
+        $gid = $) ;
+    }
+    # chown
+    if (!chown($uid, $gid, $LOG_FILE)) {
+        warn "WARNING: chown failed for $LOG_FILE: $!\n";
+    }
+    # chmod
+    if (!chmod(oct($log_file_mode), $LOG_FILE)) {
+        warn "WARNING: chmod failed for $LOG_FILE: $!\n";
+    }
+    # Логгируем успех (если уже можно)
+    my $log = get_logger();
+    $log->debug("Log file permissions set: uid=$uid, gid=$gid, mode=$log_file_mode") if $debug;
+}
+
+# === Публичная функция для смены прав на лету (если нужно) ===
+sub set_log_permissions {
+    my (%opts) = @_;
+    $log_owner_user = $opts{user} if defined $opts{user};
+    $log_owner_group = $opts{group} if defined $opts{group};
+    $log_file_mode = $opts{mode} if defined $opts{mode};
+    _set_log_file_permissions();
+}
+
+# === Конвертер уровней ===
+sub _lvl_to_log4perl {
+    my ($lvl) = @_;
+    my %map = (
+        $L_ERROR   => 'ERROR',
+        $L_WARNING => 'WARN',
+        $L_INFO    => 'INFO',
+        $L_VERBOSE => 'INFO',
+        $L_DEBUG   => 'DEBUG',
+    );
+    return $map{$lvl} || 'INFO';
+}
+
+# === Логгер ===
+sub get_logger {
+    my ($category) = @_;
+    return Log::Log4perl->get_logger($category || 'root');
+}
+
+# === Обёртки ===
+sub log_info    { _log_wrapper('info',    @_); }
+sub log_error   { _log_wrapper('error',   @_); }
+sub log_warning { _log_wrapper('warn',    @_); }
+sub log_verbose { _log_wrapper('info',    @_); }
+sub log_session { _log_wrapper('info', "SESSION: $_[0]"); }
+
+sub log_debug {
+    return unless $log_enable;
+    _log_wrapper('debug', @_) if ($debug);
+}
+
+sub log_die {
+    _log_wrapper('error', @_);
+    die ($_[0]);
+}
+
+sub _log_wrapper {
+    return unless $log_enable;
+    my ($method, @msgs) = @_;
+    my $log = get_logger();
+    for my $msg (@msgs) {
+        next unless defined $msg && length $msg;
+        for my $line (split /\n/, $msg) {
+            next unless length $line;
+            $log->$method($line);
+        }
+    }
+}
+
+# === Динамическая смена уровня логирования ===
+sub set_log_level {
+    my ($new_level) = @_;
+    $log_level = $new_level;
+    my $l4p_level = _lvl_to_log4perl($new_level);
+    my %level_map = (
+        'ERROR' => $Log::Log4perl::ERROR,
+        'WARN'  => $Log::Log4perl::WARN,
+        'INFO'  => $Log::Log4perl::INFO,
+        'DEBUG' => $Log::Log4perl::DEBUG,
+        'TRACE' => $Log::Log4perl::TRACE,
+        'OFF'   => $Log::Log4perl::OFF,
+    );
+    my $numeric_level = $level_map{$l4p_level} || $Log::Log4perl::INFO;
+    my $logger = Log::Log4perl->get_logger();
+    $logger->level($numeric_level);
+    my $appender = Log::Log4perl->appender_by_name('MainLog');
+    if ($appender) {
+        $appender->threshold($numeric_level);
+    }
+}
+
+sub wrlog {
+    return unless $log_enable;
+    my ($level, $string) = @_;
+    my %map = (
+        $W_INFO  => 'info',
+        $W_WARN  => 'warn',
+        $W_ERROR => 'error',
+        $W_DEBUG => 'debug',
+    );
+    my $method = $map{$level} || 'info';
+    my $log = get_logger();
+    for my $line (split /\n/, $string) {
+        next unless length $line;
+        $log->$method($line);
+        if ($level == $W_ERROR) { print STDERR "[$method] $line\n"; } else { print "[$method] $line\n"; }
+    }
+}
+
+log_init;
+
+1;
+}

+ 1 - 101
scripts/eyelib/main.pm

@@ -14,6 +14,7 @@ use lib "/opt/Eye/scripts";
 use base 'Exporter';
 use base 'Exporter';
 use vars qw(@EXPORT @ISA);
 use vars qw(@EXPORT @ISA);
 use eyelib::config;
 use eyelib::config;
+use eyelib::logconfig;
 use Socket;
 use Socket;
 use POSIX;
 use POSIX;
 use IO::Select;
 use IO::Select;
@@ -29,16 +30,7 @@ isNotifyUpdate
 isNotifyDelete
 isNotifyDelete
 isNotifyNone
 isNotifyNone
 hasNotifyFlag
 hasNotifyFlag
-log_file
 write_to_file
 write_to_file
-wrlog
-log_session
-log_warning
-log_info
-log_debug
-log_error
-log_verbose
-log_die
 in_array
 in_array
 timestamp
 timestamp
 do_exec
 do_exec
@@ -129,41 +121,6 @@ sub hasNotifyFlag {
 
 
 #---------------------------------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------------------------------
 
 
-sub log_file {
-    return if (!$_[0]);
-    return if (!$_[1]);
-    return if (!$_[2]);
-    
-    # Вместо die - предупреждение и возврат
-    unless (open (LG,">>$_[0]")) {
-        # Пишем в stderr как последнее средство
-        print STDERR "WARNING: Cannot open log file $_[0]: $!\n";
-        return;
-    }
-    
-    my ($sec,$min,$hour,$mday,$mon,$year) = (localtime())[0,1,2,3,4,5];
-    $mon += 1; $year += 1900;
-    my @msg = split("\n",$_[2]);
-    
-    foreach my $row (@msg) {
-        next if (!$row);
-        printf LG "%04d%02d%02d-%02d%02d%02d %s [%d] %s\n",$year,$mon,$mday,$hour,$min,$sec,$_[1],$$,$row;
-    }
-    
-    close (LG);
-    
-    if ($< ==0) {
-        my $uid = getpwnam $log_owner_user;
-        my $gid = getgrnam $log_owner_user;
-        if (!$gid) { $gid=getgrnam "root"; }
-        if (!$uid) { $uid=getpwnam "root"; }
-        chown $uid, $gid, $_[0];
-        chmod oct("0660"), $_[0];
-    }
-}
-
-#---------------------------------------------------------------------------------------------------------
-
 sub write_to_file {
 sub write_to_file {
 return if (!$_[0]);
 return if (!$_[0]);
 return if (!$_[1]);
 return if (!$_[1]);
@@ -196,56 +153,6 @@ close (LG);
 
 
 #---------------------------------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------------------------------
 
 
-sub wrlog {
-my $level = shift;
-my $string = shift;
-my $PRN_LEVEL = 'INFO:';
-if ($level == $W_INFO)  { log_info($string); }
-if ($level == $W_ERROR) { $PRN_LEVEL = 'ERROR:'; log_error($string); }
-if ($level == $W_DEBUG) { $PRN_LEVEL = 'DEBUG'; log_debug($string); }
-my @msg = split("\n",$string);
-foreach my $row (@msg) {
-    next if (!$row);
-    print $PRN_LEVEL.' '.$row."\n";
-    }
-}
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_session { log_file($LOG_COMMON,"SESSION:",$_[0]) if ($log_enable); }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_info { log_file($LOG_COMMON,"INFO:",$_[0]) if ($log_enable); }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_verbose { log_file($LOG_COMMON,"VERBOSE:",$_[0]) if ($log_enable); }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_warning { log_file($LOG_COMMON,"WARN:",$_[0]) if ($log_enable); }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_debug { log_file($LOG_DEBUG,"DEBUG:",$_[0]) if $debug; }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_error { log_file($LOG_ERR,"ERROR:",$_[0]) if ($log_enable); }
-
-#---------------------------------------------------------------------------------------------------------
-
-sub log_die {
-wrlog($W_ERROR,$_[0]);
-my $worktime = time()-$BASETIME;
-log_info("Script work $worktime sec.");
-#sendEmail("$HOSTNAME - $MY_NAME die! ","Process: $MY_NAME aborted with error:\n$_[0]");
-die ($_[0]);
-}
-
-#---------------------------------------------------------------------------------------------------------
-
 sub timestamp {
 sub timestamp {
 my $worktime = time()-$BASETIME;
 my $worktime = time()-$BASETIME;
 #print "TimeStamp: $worktime sec.\n";
 #print "TimeStamp: $worktime sec.\n";
@@ -913,12 +820,5 @@ sub htmlspecialchars {
 
 
 #---------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------
 
 
-#log_file($LOG_COMMON,"INFO:","----------------------------------------------------------------------------------------");
-#log_file($LOG_COMMON,"INFO:","Run script $0. Pid: $$ Pid file: $SPID.pid");
-#log_file($LOG_COMMON,"INFO:","User uid: $< Effective uid: $>");
-#log_file($LOG_COMMON,"INFO:","Status:");
-#log_file($LOG_COMMON,"INFO:","Logging enabled: $log_enable");
-#log_file($LOG_COMMON,"INFO:","Logging debug: $debug");
-
 1;
 1;
 }
 }

+ 1 - 0
scripts/eyelib/nagios.pm

@@ -14,6 +14,7 @@ use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::snmp;
 use eyelib::snmp;
+use eyelib::logconfig;
 use Time::Local;
 use Time::Local;
 use Data::Dumper;
 use Data::Dumper;
 
 

+ 1 - 0
scripts/eyelib/net_utils.pm

@@ -16,6 +16,7 @@ use FileHandle;
 use POSIX;
 use POSIX;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use Net::Ping;
 use Net::Ping;
 use Net::Patricia;
 use Net::Patricia;
 use NetAddr::IP;
 use NetAddr::IP;

+ 1 - 0
scripts/eyelib/rest_api.pm

@@ -17,6 +17,7 @@ use HTTP::Request;
 use LWP;
 use LWP;
 use URI::Encode;
 use URI::Encode;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use Data::Dumper;
 use Data::Dumper;
 use IO::Socket::SSL;
 use IO::Socket::SSL;
 use JSON;
 use JSON;

+ 250 - 104
scripts/eyelib/snmp.pm

@@ -15,42 +15,62 @@ use vars qw(@EXPORT @ISA);
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use Net::SNMP;
 use Net::SNMP;
 
 
 @ISA = qw(Exporter);
 @ISA = qw(Exporter);
 @EXPORT = qw(
 @EXPORT = qw(
-snmp_set_int
 snmp_get_request
 snmp_get_request
+snmp_set_int
 get_arp_table
 get_arp_table
-get_fdb_table
+snmp_ping
+get_ifmib_index_table
 get_mac_table
 get_mac_table
+get_fdb_table
 get_vlan_at_port
 get_vlan_at_port
 get_switch_vlans
 get_switch_vlans
 get_snmp_ifindex
 get_snmp_ifindex
-get_ifmib_index_table
 getIpAdEntIfIndex
 getIpAdEntIfIndex
 get_interfaces
 get_interfaces
 get_router_state
 get_router_state
 snmp_get_req
 snmp_get_req
 snmp_get_oid
 snmp_get_oid
 snmp_walk_oid
 snmp_walk_oid
+oid_base_match
+snmp_oid_compare
 table_callback
 table_callback
+init_snmp
+setCommunity
+
 $ifAlias
 $ifAlias
 $ifName
 $ifName
 $ifDescr
 $ifDescr
 $ifIndex
 $ifIndex
 $ifIndex_map
 $ifIndex_map
+$ipAdEntIfIndex
 $arp_oid
 $arp_oid
 $ipNetToMediaPhysAddress
 $ipNetToMediaPhysAddress
-$ipAdEntIfIndex
 $fdb_table_oid
 $fdb_table_oid
 $fdb_table_oid2
 $fdb_table_oid2
-$cisco_vlan_oid
 $dot1qPortVlanEntry
 $dot1qPortVlanEntry
-$fdb_table;
+$cisco_vlan_oid
+$sysUpTimeInstance
+$ifPortStatus
+$ifPortAdminStatus
+$bgp_prefixes
+$bgp_aslist
+$hrDeviceDescr
+$hrProcessorLoad
+$hrMemorySize
+$hrStorageIndex
+$hrStorageType
+$hrStorageDescr
+$hrStorageAllocationUnits
+$hrStorageSize
+$hrStorageUsed
+$fdb_table
 $snmp_timeout
 $snmp_timeout
-setCommunity
-init_snmp
+
 );
 );
 
 
 
 
@@ -77,7 +97,20 @@ our $dot1qPortVlanEntry ='.1.3.6.1.2.1.17.7.1.4.5.1.1';
 #CISCO-ES-STACK-MIB::
 #CISCO-ES-STACK-MIB::
 our $cisco_vlan_oid='.1.3.6.1.4.1.9.9.46.1.3.1.1.2';
 our $cisco_vlan_oid='.1.3.6.1.4.1.9.9.46.1.3.1.1.2';
 
 
-our $fdb_table;
+our $sysUpTimeInstance = '1.3.6.1.2.1.1.3.0';
+our $ifPortStatus      = '1.3.6.1.2.1.2.2.1.8';
+our $ifPortAdminStatus = '1.3.6.1.2.1.2.2.1.7';
+our $bgp_prefixes      = '1.3.6.1.4.1.9.9.187.1.2.4.1.1';
+our $bgp_aslist        = '1.3.6.1.2.1.15.3.1.9';
+our $hrDeviceDescr     = '1.3.6.1.2.1.25.3.2.1.3';
+our $hrProcessorLoad   = '1.3.6.1.2.1.25.3.3.1.2';
+our $hrMemorySize      = '1.3.6.1.2.1.25.2.2.0';
+our $hrStorageIndex    = '1.3.6.1.2.1.25.2.3.1.1';
+our $hrStorageType     = '1.3.6.1.2.1.25.2.3.1.2';
+our $hrStorageDescr    = '1.3.6.1.2.1.25.2.3.1.3';
+our $hrStorageAllocationUnits = '1.3.6.1.2.1.25.2.3.1.4';
+our $hrStorageSize     = '1.3.6.1.2.1.25.2.3.1.5';
+our $hrStorageUsed     = '1.3.6.1.2.1.25.2.3.1.6';
 
 
 our $snmp_timeout = 15;
 our $snmp_timeout = 15;
 
 
@@ -161,6 +194,37 @@ sub get_arp_table {
     return $arp;
     return $arp;
 }
 }
 
 
+#---------------------------------------------------------------------------------
+
+sub snmp_ping {
+    my ($host,$snmp) = @_;
+
+    my @test_oids = (
+        '.1.3.6.1.2.1.1.1.0',  # model
+        '.1.3.6.1.2.1.1.3.0',  # uptime
+        '.1.3.6.1.2.1.1.5.0',  # name
+    );
+
+    my $result;
+    my $old_sig_alarm = $SIG{ALRM};
+
+    $SIG{ALRM} = sub { die "Timeout 5 sec reached.\n" };
+    alarm($WAIT_TIME // 5);
+
+    eval {
+        foreach my $oid (@test_oids) {
+            $result = snmp_get_request($host,$oid,$snmp);
+            last if defined $result;
+        }
+    };
+    my $eval_error = $@;
+
+    alarm(0);
+    $SIG{ALRM} = $old_sig_alarm;
+
+    return (defined $result && !$eval_error) ? 1 : 0;
+}
+
 #-------------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------------
 
 
 sub get_ifmib_index_table {
 sub get_ifmib_index_table {
@@ -215,8 +279,6 @@ return $ifmib_map;
 sub get_mac_table {
 sub get_mac_table {
     my ($host,$snmp,$oid,$index_map) = @_;
     my ($host,$snmp,$oid,$index_map) = @_;
     my $fdb;
     my $fdb;
-    #need for callback
-    $fdb_table=$oid;
     my $fdb_table1 = snmp_get_oid($host,$snmp,$oid);
     my $fdb_table1 = snmp_get_oid($host,$snmp,$oid);
     if (!$fdb_table1) { $fdb_table1=snmp_walk_oid($host,$snmp,$oid,undef); }
     if (!$fdb_table1) { $fdb_table1=snmp_walk_oid($host,$snmp,$oid,undef); }
     if ($fdb_table1) {
     if ($fdb_table1) {
@@ -430,130 +492,214 @@ return $table;
 #-------------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------------
 
 
 sub snmp_walk_oid {
 sub snmp_walk_oid {
+    my ($host, $snmp, $oid, $opt) = @_;
+    $opt ||= {};
+
+    my $nonblocking = $opt->{nonblocking} // 1;
+    log_debug("Starting SNMP walk on $host, OID: $oid, nonblocking=" . ($nonblocking ? 1 : 0)) if defined &log_debug;
+    my $session = init_snmp($host, $snmp, 'ro', $nonblocking);
+    unless ($session) {
+        log_debug("Failed to initialize SNMP session for $host") if defined &log_debug;
+        return;
+    }
+    my %table;
+    if ($nonblocking) {
+        # Async walk через callback
+        log_debug("Sending first get_bulk_request for OID $oid") if defined &log_debug;
+        my $result = $session->get_bulk_request(
+            -varbindlist    => [$oid],
+            -callback       => [\&table_callback, \%table, $oid, undef],
+            -maxrepetitions => 10,
+        );
+        unless (defined $result) {
+            log_debug("SNMP request error ($host): " . $session->error) if defined &log_debug;
+            $session->close();
+            return;
+        }
+        # Запускаем dispatcher для обработки async запросов
+        eval {
+            log_debug("Starting snmp_dispatcher for $host") if defined &log_debug;
+            snmp_dispatcher();
+        };
+        if ($@) {
+            log_debug("SNMP dispatcher exception ($host): $@") if defined &log_debug;
+            $session->close();
+            return;
+        }
+    }
+    else {
+        # Blocking walk через get_next
+        log_debug("Starting blocking SNMP walk for OID $oid") if defined &log_debug;
+        my $current_oid = $oid;
+        while (1) {
+            my $result = $session->get_next_request(-varbindlist => [$current_oid]);
+            unless (defined $result) {
+                log_debug("SNMP request error ($host): " . $session->error) if defined &log_debug;
+                last;
+            }
+            my $list = $session->var_bind_list();
+            last unless defined $list;
+            my $stop = 0;
+            for my $k (keys %$list) {
+                unless (oid_base_match($oid, $k)) {
+                    log_debug("OID $k outside root $oid, stopping walk") if defined &log_debug;
+                    $stop = 1;
+                    last;
+                }
+                $table{$k} = $list->{$k};
+                log_debug("Stored OID $k = $list->{$k}") if defined &log_debug;
+                $current_oid = $k;
+            }
+            last if $stop;
+        }
+    }
+    if ($session->error) {
+        log_debug("SNMP runtime error ($host): " . $session->error) if defined &log_debug;
+    }
+    $session->close();
+    log_debug("SNMP walk finished on $host, total OIDs collected: " . scalar keys %table) if defined &log_debug;
+    return \%table;
+}
 
 
-my $host = shift;
-my $snmp = shift;
-my $oid = shift;
-my $rw = 'ro';
+#-------------------------------------------------------------------------------------
 
 
-### open SNMP session
-my ($session, $error);
+# проверка что OID начинается с root
+sub oid_base_match {
+    my ($base, $oid) = @_;
+    return defined($oid) && defined($base) && index($oid, $base) == 0;
+}
 
 
-if ($snmp->{version} <= 2) {
-        ($session, $error) = Net::SNMP->session(
-		-hostname  => $host,
-		-community => $snmp->{'ro-community'} ,
-		-version   => $snmp->{version},
-		-port      => $snmp->{port},
-		-timeout   => $snmp->{timeout},
-		-nonblocking => 1,
-		-translate   => [-octetstring => 0],
-		);
-	} else {
-	($session, $error) = Net::SNMP->session(
-		-hostname     => $host,
-		-version      => 'snmpv3',
-		-username     => $snmp->{$rw.'-user'},
-		-authprotocol => $snmp->{'auth-proto'},
-		-privprotocol => $snmp->{'priv-proto'},
-		-authpassword => $snmp->{$rw.'-password'},
-		-privpassword => $snmp->{$rw.'-password'},
-		-port         => $snmp->{port},
-		-timeout      => $snmp->{timeout},
-		-nonblocking  => 1,
-		-translate    => [-octetstring => 0],
-		);
-	}
+#-------------------------------------------------------------------------------------
 
 
-return if (!defined($session) or !$session);
+sub snmp_oid_compare {
+    my ($oid1, $oid2) = @_;
 
 
-my %table; # Hash to store the results
+    return 0  if !defined $oid1 && !defined $oid2;
+    return 1  if !defined $oid2;
+    return -1 if !defined $oid1;
 
 
-my $result = $session->get_bulk_request(
-      -varbindlist    => [ $oid ],
-      -callback       => [ \&table_callback, \%table ],
-      -maxrepetitions => 10,
-   );
+    # Удаляем ведущую точку для единообразия
+    $oid1 =~ s/^\.//;
+    $oid2 =~ s/^\.//;
 
 
-snmp_dispatcher();
-$session->close();
+    my @a = split /\./, $oid1;
+    my @b = split /\./, $oid2;
+    my $len = @a < @b ? @a : @b;
+
+    # Сравниваем покомпонентно как числа
+    for (my $i = 0; $i < $len; $i++) {
+        return -1 if $a[$i] < $b[$i];
+        return 1  if $a[$i] > $b[$i];
+    }
 
 
-return \%table;
+    # Если префиксы равны, сравниваем длину
+    return @a <=> @b;
 }
 }
 
 
 #-------------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------------
 
 
-sub table_callback  {
-my ($session, $table) = @_;
-my $list = $session->var_bind_list();
+sub table_callback {
+    my ($session, $table, $root_oid, $last_oid) = @_;
 
 
-if (!defined $list) {
-    printf "ERROR: %s\n", $session->error();
-    return;
-    }
+    my $list = $session->var_bind_list();
 
 
-my @names = $session->var_bind_names();
-my $next  = undef;
+    unless (defined $list) {
+        log_debug("SNMP error: " . $session->error) if defined &log_debug;
+        log_debug("Exiting callback: undefined var_bind_list") if defined &log_debug;
+        return;
+    }
 
 
-while (@names) {
-    $next = shift @names;
-    if (!oid_base_match($fdb_table, $next)) { return; }
-    $table->{$next} = $list->{$next};
+    my @names = sort { snmp_oid_compare($a, $b) } $session->var_bind_names();
+    unless (@names) {
+        log_debug("No OIDs returned in this callback") if defined &log_debug;
+        return;
     }
     }
 
 
-my $result = $session->get_bulk_request( -varbindlist    => [ $next ], -maxrepetitions => 10);
+    my $next;
+    while (@names) {
+        $next = shift @names;
+        # Вышли за пределы таблицы
+        unless (oid_base_match($root_oid, $next)) {
+            log_debug("OID $next outside of root $root_oid. Exiting callback.") if defined &log_debug;
+            return;
+        }
+        # Защита от OID not increasing
+        if (defined $last_oid && snmp_oid_compare($next, $last_oid) <= 0) {
+            log_debug("OID not increasing: $next <= $last_oid. Exiting callback.") if defined &log_debug;
+            return;
+        }
+        my $value = $list->{$next};
+        # endOfMibView
+        unless (defined $value) {
+            log_debug("endOfMibView reached at OID $next. Exiting callback.") if defined &log_debug;
+            return;
+        }
+        $table->{$next} = $value;
+        log_debug("Stored OID $next = $value") if defined &log_debug;
+        $last_oid = $next;
+    }
 
 
-if (!defined $result) {
-     printf "ERROR: %s.\n", $session->error();
+    # Запрос следующего блока
+    my $result = $session->get_bulk_request(
+        -varbindlist    => [$next],
+        -maxrepetitions => 10,
+        -callback       => [\&table_callback, $table, $root_oid, $last_oid],
+    );
+    unless (defined $result) {
+        log_debug("SNMP get_bulk_request failed for OID $next: " . $session->error) if defined &log_debug;
+    }
+    else {
+        log_debug("Scheduled next get_bulk_request starting from OID $next") if defined &log_debug;
     }
     }
-return;
 }
 }
 
 
-
 #-------------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------------
 
 
 sub init_snmp {
 sub init_snmp {
+    my ($host, $snmp, $rw, $nonblocking) = @_;
+    return unless defined $host && $host ne '';
+
+    $rw ||= 'ro';
 
 
-    my ($host,$snmp,$rw) = @_;
+    my $community = ($rw eq 'rw')
+        ? $snmp->{'rw-community'}
+        : $snmp->{'ro-community'};
 
 
-    return if (!$host);
+    my %opts = (
+        -hostname  => $host,
+        -port      => $snmp->{port} // 161,
+        -timeout   => $snmp->{timeout} // 2,
+        -translate => [-octetstring => 0],
+    );
 
 
-    my $community = $snmp->{'ro-community'};
-    if (!$rw) { $rw = 'ro' }
-	    else {
-	    $rw = 'rw';
-	    $community = $snmp->{'rw-community'};
-	    }
+    $opts{-nonblocking} = 1 if $nonblocking;
 
 
-    ### open SNMP session
     my ($session, $error);
     my ($session, $error);
 
 
-    if ($snmp->{version} <=2) {
+    if (($snmp->{version} // 2) <= 2) {
         ($session, $error) = Net::SNMP->session(
         ($session, $error) = Net::SNMP->session(
-		-hostname  => $host,
-		-community => $community ,
-		-version   => $snmp->{'version'},
-		-port      => $snmp->{port},
-		-timeout   => $snmp->{timeout},
-		);
-	} else {
-	($session, $error) = Net::SNMP->session(
-		-hostname     => $host,
-		-version      => 'snmpv3',
-		-username     => $snmp->{$rw.'-user'},
-		-authprotocol => $snmp->{'auth-proto'},
-		-privprotocol => $snmp->{'priv-proto'},
-		-authpassword => $snmp->{$rw.'-password'},
-		-privpassword => $snmp->{$rw.'-password'},
-		-port         => $snmp->{port},
-		-timeout      => $snmp->{timeout},
-		);
-	}
-    if ($error) {
-        log_debug("SNMP init-request status for $host:");
-        log_debug(Dumper($error));
-        }
-    return if (!defined($session) or !$session);
+            %opts,
+            -community => $community,
+            -version   => $snmp->{version} // 2,
+        );
+    }
+    else {
+        ($session, $error) = Net::SNMP->session(
+            %opts,
+            -version      => 'snmpv3',
+            -username     => $snmp->{$rw . '-user'},
+            -authprotocol => $snmp->{'auth-proto'},
+            -privprotocol => $snmp->{'priv-proto'},
+            -authpassword => $snmp->{$rw . '-password'},
+            -privpassword => $snmp->{$rw . '-password'},
+        );
+    }
+
+    if (!defined $session) {
+        log_debug("SNMP init failed for $host: $error") if defined &log_debug;
+        return;
+    }
+
     return $session;
     return $session;
 }
 }
 
 

+ 3 - 0
scripts/fetch_new_arp.pl

@@ -23,6 +23,7 @@ use Date::Parse;
 use Socket;
 use Socket;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::snmp;
 use eyelib::snmp;
 use eyelib::database;
 use eyelib::database;
@@ -156,6 +157,7 @@ foreach my $router (@router_ref) {
     my $tmp_dbh = init_db();
     my $tmp_dbh = init_db();
     if (apply_device_lock($tmp_dbh, $router->{id})) {
     if (apply_device_lock($tmp_dbh, $router->{id})) {
         $arp_table = get_arp_table($router_ip, $router->{snmp});
         $arp_table = get_arp_table($router_ip, $router->{snmp});
+        log_debug("ARP TABLE at router: $router_ip".Dumper($arp_table));
         unset_lock_discovery($tmp_dbh, $router->{id});
         unset_lock_discovery($tmp_dbh, $router->{id});
     }
     }
     $tmp_dbh->disconnect;
     $tmp_dbh->disconnect;
@@ -300,6 +302,7 @@ foreach my $device (@device_list) {
     if (apply_device_lock($tmp_dbh, $device->{id})) {
     if (apply_device_lock($tmp_dbh, $device->{id})) {
         my $fdb = get_fdb_table($device->{ip}, $device->{snmp});
         my $fdb = get_fdb_table($device->{ip}, $device->{snmp});
         unset_lock_discovery($tmp_dbh, $device->{id});
         unset_lock_discovery($tmp_dbh, $device->{id});
+        log_debug("MAC TABLE at device: $device->{ip}".Dumper($fdb));
         $result->{id} = $device->{id};
         $result->{id} = $device->{id};
         $result->{fdb} = $fdb;
         $result->{fdb} = $fdb;
     }
     }

+ 1 - 25
scripts/garbage.pl

@@ -21,6 +21,7 @@ use eyelib::config;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
+use eyelib::logconfig;
 use eyelib::main;
 use eyelib::main;
 use DateTime;
 use DateTime;
 use Fcntl qw(:flock);
 use Fcntl qw(:flock);
@@ -32,31 +33,6 @@ flock(SELF, LOCK_EX | LOCK_NB) or exit 1;
 # Number of days to retain debug-level log entries
 # Number of days to retain debug-level log entries
 my $debug_history = 3;
 my $debug_history = 3;
 
 
-# List of database tables eligible for optimization
-#my @db_tables = (
-#    'connections',
-#    'device_l3_interfaces',
-#    'device_ports',
-#    'user_list',
-#    'user_auth',
-#    'unknown_mac',
-#    'user_stats',
-#    'user_stats_full',
-#    'dhcp_log',
-#    'worklog',
-#    'remote_syslog',
-#    'traffic_detail',
-#);
-
-
-# Optimization flag (disabled by default)
-#my $optimize = 0;
-
-# Enable table optimization if "optimize" is passed as the first argument
-#if ($ARGV[0] =~ /optimize/i) {
-#    $optimize = 1;
-#}
-
 db_log_info($dbh, 'Garbage collection started.');
 db_log_info($dbh, 'Garbage collection started.');
 
 
 # Helper: Check if a given IP (as integer) belongs to any DHCP pool
 # Helper: Check if a given IP (as integer) belongs to any DHCP pool

+ 1 - 0
scripts/gen_nagios_config.pl

@@ -25,6 +25,7 @@ use Net::Ping;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::nagios;
 use eyelib::nagios;
+use eyelib::logconfig;
 use eyelib::snmp;
 use eyelib::snmp;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 1 - 0
scripts/hmonitor.pl

@@ -20,6 +20,7 @@ use eyelib::config;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::nagios;
 use eyelib::nagios;
 use Data::Dumper;
 use Data::Dumper;
 use Time::Local;
 use Time::Local;

+ 1 - 0
scripts/print-dnsmasq.pl

@@ -22,6 +22,7 @@ use NetAddr::IP;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;

+ 1 - 0
scripts/restart_port_snmp.pl

@@ -18,6 +18,7 @@ use FileHandle;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 1 - 0
scripts/stat-sync.pl

@@ -19,6 +19,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use strict;
 use strict;
 use Getopt::Long;
 use Getopt::Long;

+ 1 - 0
scripts/sync_iptables.pl

@@ -25,6 +25,7 @@ use Net::Patricia;
 use Date::Parse;
 use Date::Parse;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use DBI;
 use DBI;
 use Fcntl qw(:flock);
 use Fcntl qw(:flock);

+ 1 - 0
scripts/sync_mikrotik.pl

@@ -22,6 +22,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::cmd;
 use eyelib::cmd;
 use Net::Patricia;
 use Net::Patricia;
+use eyelib::logconfig;
 use Date::Parse;
 use Date::Parse;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;

+ 1 - 0
scripts/sync_mikrotik_poe_monitor.pl

@@ -23,6 +23,7 @@ use Net::Patricia;
 use Date::Parse;
 use Date::Parse;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use DBI;
 use DBI;
 use utf8;
 use utf8;

+ 1 - 0
scripts/syslog-stat.pl

@@ -21,6 +21,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 use Data::Dumper;
 use Data::Dumper;
 use DBI;
 use DBI;
 use Time::Local;
 use Time::Local;

+ 1 - 0
scripts/updates/2-8-0/after_sql.pl

@@ -14,6 +14,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 use strict;
 use strict;
 use warnings;
 use warnings;
 use Data::Dumper;
 use Data::Dumper;

+ 1 - 0
scripts/updates/db-patch-mysql-utf8.pl

@@ -18,6 +18,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 

+ 1 - 0
scripts/updates/upgrade.pl

@@ -17,6 +17,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 use Data::Dumper;
 use Data::Dumper;
 use strict;
 use strict;
 use warnings;
 use warnings;

+ 1 - 0
scripts/utils/backupcfg.pl

@@ -20,6 +20,7 @@ use FileHandle;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;

+ 1 - 0
scripts/utils/bind/print-dns-zones.pl

@@ -19,6 +19,7 @@ use Net::Patricia;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 
 

+ 5 - 4
scripts/utils/import-system-dev.pl

@@ -15,10 +15,11 @@ no warnings 'utf8';
 use FindBin '$Bin';
 use FindBin '$Bin';
 use lib "$Bin/";
 use lib "$Bin/";
 use Data::Dumper;
 use Data::Dumper;
-use Rstat::config;
-use Rstat::main;
-use Rstat::database;
-use Rstat::net_utils;
+use eyelib::config;
+use eyelib::main;
+use eyelib::logconfig;
+use eyelib::database;
+use eyelib::net_utils;
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 

+ 1 - 0
scripts/utils/import/import_auth.pl

@@ -17,6 +17,7 @@ use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use Net::Patricia;
 use Net::Patricia;

+ 1 - 0
scripts/utils/mac-oids/update-mac-vendors.pl

@@ -16,6 +16,7 @@ use lib "/opt/Eye/scripts";
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;

+ 1 - 0
scripts/utils/oxidized/print_devices_oxi.pl

@@ -18,6 +18,7 @@ use Data::Dumper;
 use Socket;
 use Socket;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 
 

+ 1 - 0
scripts/utils/parse_flow.pl

@@ -25,6 +25,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use Parallel::ForkManager;
 use Parallel::ForkManager;
 
 

+ 1 - 0
scripts/utils/print-ou-ip.pl

@@ -19,6 +19,7 @@ use Net::Patricia;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 1 - 0
scripts/utils/print_cacti_create.pl

@@ -17,6 +17,7 @@ use Date::Parse;
 use eyelib::config;
 use eyelib::config;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 
 
 
 
 ##### unknown mac clean ############
 ##### unknown mac clean ############

+ 1 - 0
scripts/utils/print_cacti_hosts.pl

@@ -16,6 +16,7 @@ use Date::Parse;
 use eyelib::config;
 use eyelib::config;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
+use eyelib::logconfig;
 
 
 ##### unknown mac clean ############
 ##### unknown mac clean ############
 
 

+ 1 - 0
scripts/utils/print_devices.pl

@@ -21,6 +21,7 @@ use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use NetAddr::IP;
 use NetAddr::IP;
 
 

+ 1 - 0
scripts/utils/radius/print_huntgroups.pl

@@ -18,6 +18,7 @@ use Socket;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::net_utils;
 use eyelib::net_utils;
+use eyelib::logconfig;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;
 
 

+ 1 - 0
scripts/utils/reaply_rules.pl

@@ -25,6 +25,7 @@ use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use File::Basename;
 use File::Basename;

+ 1 - 0
scripts/utils/scan_ipcam.pl

@@ -24,6 +24,7 @@ use Net::SNMP qw(ticks_to_time TRANSLATE_NONE);
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use Fcntl qw(:flock);
 use Fcntl qw(:flock);
 
 

+ 1 - 0
scripts/utils/set_dns_record.pl

@@ -23,6 +23,7 @@ use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
 use eyelib::database;
 use eyelib::database;
+use eyelib::logconfig;
 use eyelib::common;
 use eyelib::common;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use File::Basename;
 use File::Basename;

+ 1 - 0
scripts/utils/set_port_descr.pl

@@ -20,6 +20,7 @@ use FileHandle;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 4 - 4
scripts/utils/trap_restart.pl

@@ -15,10 +15,10 @@ use strict;
 use Time::Local;
 use Time::Local;
 use FileHandle;
 use FileHandle;
 use Data::Dumper;
 use Data::Dumper;
-use Rstat::config;
-use Rstat::main;
-use Rstat::database;
-use Rstat::net_utils;
+use eyelib::config;
+use eyelib::main;
+use eyelib::database;
+use eyelib::net_utils;
 use DBI;
 use DBI;
 
 
 $debug=0;
 $debug=0;

+ 1 - 0
scripts/utils/win32/print-dhcpd-netsh.pl

@@ -19,6 +19,7 @@ use Net::Patricia;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;

+ 1 - 0
scripts/utils/win32/sync-dhcpd-netsh.pl

@@ -18,6 +18,7 @@ use Time::Local;
 use Data::Dumper;
 use Data::Dumper;
 use eyelib::config;
 use eyelib::config;
 use eyelib::main;
 use eyelib::main;
+use eyelib::logconfig;
 use eyelib::net_utils;
 use eyelib::net_utils;
 use eyelib::database;
 use eyelib::database;
 use eyelib::common;
 use eyelib::common;