netniV / cisco-sfp

Cisco SFP Statistics for Cacti 1.x. This is to host code from the Cacti forums for others to use. I do not actively maintain this code, but welcome pull requests from others where they believe this can be improved. Cisco SFP Statistics for Cacti (c) 2007-2008 sodium in 2017
https://forums.cacti.net/viewtopic.php?f=19&t=23089 for others
GNU General Public License v2.0
7 stars 2 forks source link

Wrong readings on Cisco 3850 #10

Open pyron83 opened 1 year ago

pyron83 commented 1 year ago

I'm having a weird issue: when I read optic values from a Cisco 3850, I get same values scrambled with this script. For example I get the "Current (milliamperes)" value instead of the "Optical Receive Power (dBm)". I gave a look at the script but I think the indexing part is right. Do you have any idea?

netniV commented 1 year ago

If you take a look at the work done on https://github.com/netniV/cisco-sfp/issues/7 you will see that there can be issues of the type isn't the supported one. Do a manual walk (as per that issue) to see if that helps. Also, there is an updated version of this template that @Luth1ng put together which I have now merged. This replaces the Cacti 0.8.8 version of the template which I have now archived for historic purposes.

pyron83 commented 1 year ago

If you take a look at the work done on #7 you will see that there can be issues of the type isn't the supported one. Do a manual walk (as per that issue) to see if that helps. Also, there is an updated version of this template that @Luth1ng put together which I have now merged. This replaces the Cacti 0.8.8 version of the template which I have now archived for historic purposes.

Hi, today I replaced the old template with the new one. Now I can't collect any data on Catalysts (we have 3650, 3850 and 2960). Every graph gives -nAn (OFC I deleted the old graphs and data sources and made the new one with this template). But if I do manually an snmpwalk using the oids referenced in the PHP code, it works and I can retrieve SFP tx and rx. Any data needed to debug this?

netniV commented 1 year ago

Sounds like something @Luth1ng implemented broke it. I don't have any of these devices, so I would need to have access to one to properly debug the script. If you are able to do that work and advise on a fix, or even create a pull request it would be welcome.

pyron83 commented 1 year ago

I can do the debug part, I just need some assistance 'cause well I don't debug on Cacti from ages (last time was 2018 when I opened the issue on the old SFP script). Let me know what should I do and I'll collect the data for you. Thanks.

netniV commented 1 year ago

Grab the command line from the poller out and then run it manually against the script. You will need to do that as the website user and see the output. You can add in extra output but check whether you are running from script server (you'll see a check that does that initially). Any extra output to script server will cause a failure.

pyron83 commented 1 year ago

I'm trying to fetch the logs, but there is one thing I do not understand, that "output: U" at the end of the command:

www-data@someserver$ grep myhost 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] HT[1] DS[8240] TT[2.16] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '2127', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] DS[8240] ERROR: Empty result [myhost.domain.com]: '/usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '2127'' 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] WARNING: Invalid Response, Device[169] HT[1] DS[8240] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '2127', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] HT[1] DS[8240] TT[1.98] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '2127', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] DS[8239] ERROR: Empty result [myhost.domain.com]: '/usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '1153'' 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] WARNING: Invalid Response, Device[169] HT[1] DS[8239] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '1153', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] HT[1] DS[8239] TT[2.47] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' '1153', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] DS[8239] ERROR: Empty result [myhost.domain.com]: '/usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '1153'' 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] WARNING: Invalid Response, Device[169] HT[1] DS[8239] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '1153', output: U 2022/12/14 16:11:53 - SPINE: Poller[1] PID[2522700] Device[169] HT[1] DS[8239] TT[2.19] SCRIPT: /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '1153', output: U

If i execute the command without and with "output U" as www-data (cacti user):

www-data@someserver:/var/log/cacti$ php /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '2127' -2.3 www-data@someserver::/var/log/cacti$ php /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '2127', output: U -40

What is that "output: U"? It looks like it forces the value to a -40.

netniV commented 1 year ago

Basically, that means it was not getting a value. What value do you get for .1.3.6.1.4.1.9.9.91.1.1.1.1.5.2127 ? and .1.3.6.1.4.1.9.9.91.1.1.1.1.4.2127 ?

pyron83 commented 1 year ago

Basically, that means it was not getting a value. What value do you get for .1.3.6.1.4.1.9.9.91.1.1.1.1.5.2127 ? and .1.3.6.1.4.1.9.9.91.1.1.1.1.4.2127 ?

If i do an snmpwalk manually:

myuser@myserver:~$ snmpbulkwalk -On -v2c -cmycomm myswitch .1.3.6.1.4.1.9.9.91.1.1.1.1.4.2127
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2127 = INTEGER: -23
myuser@myserver:~$ snmpbulkwalk -On -v2c -cmycomm myswitch .1.3.6.1.4.1.9.9.91.1.1.1.1.5.2127
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2127 = INTEGER: 1

maybe I'm wrong, but it's not the same of:

"www-data@someserver:/var/log/cacti$ php /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' '2127'
-2.3"

that I reported in the post above? It looks it's applied some sort of CDEF or something similar.

netniV commented 1 year ago

Out of curiosity what version of spine/cacti are you using?

pyron83 commented 1 year ago

Out of curiosity what version of spine/cacti are you using?

user@myserver:~$ dpkg -l | grep -i cacti
ii  cacti                              1.2.16+ds1-2+deb11u1                  all          web interface for graphing of monitoring systems
ii  cacti-spine                        1.2.16-1                              amd64        Multi-Threading poller for cacti
user@myserver:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye

btw 1.2.16 is the last Cacti release available on Debian Stable (11/bullseye)

netniV commented 1 year ago

That was probably the version available before EOL for Bullseye I guess. @paulgevers would be able to confirm that.

I will have to check later if there are any known issues between that version and now with number parsing.

pyron83 commented 1 year ago

In the worst scenario, I could upgrade Cacti from "testing". OFC I would prefer to mantain the stable version. I'll wait for your checks. Thanks

paulgevers commented 1 year ago

If there's a clear bug, we can try and get it fixed in bullseye.

@netniV I'm not sure what you mean with

the version available before EOL for Bullseye

Are you asking if this is the latest version in bullseye? https://tracker.debian.org/pkg/cacti confirms that's the latest version (in bullseye-security).

netniV commented 1 year ago

Yeah that is what I was asking. Thanks Paul. Helpful as always 😀

paulgevers commented 1 year ago

@pyron83 by the way, if this is solved in testing and the bug doesn't warrant a fix in bullseye (or that takes too long), I'm willing to support cacti again in backports. Would that help you?

netniV commented 1 year ago

@paulgevers Not convinced it is a bug yet, but thanks for letting us know.

netniV commented 1 year ago

@pyron83 Can you give me a full SNMP walk via email to netniv@cacti.net ? I would like to simulate what's going on and see if the issue is in the script or the cacti core. Feel free to adjust the output to remove any community, passwords or other sensitive data as long as it doesn't affect the overall usage.

pyron83 commented 1 year ago

@pyron83 Can you give me a full SNMP walk via email to netniv@cacti.net ? I would like to simulate what's going on and see if the issue is in the script or the cacti core. Feel free to adjust the output to remove any community, passwords or other sensitive data as long as it doesn't affect the overall usage.

Hi, are you sure you want a FULL snmpwalk and not only of the OIDs queried by the script?

# PortIndex - 1.3.6.1.2.1.47.1.1.1.1.2
# entSensorValue - 1.3.6.1.4.1.9.9.91.1.1.1.1.4 (RX = .4.[index] TX =.4.[index] + 1)
# entSensorStatus - 1.3.6.1.4.1.9.9.91.1.1.1.1.5 (1 = ok, 2 = unavailable, 3 = nonoperational)
# entSensorType - 1.3.6.1.4.1.9.9.91.1.1.1.1.1 (output type 14 = in dBm)

these are the values in the heading of the script

If I just have to do these snmpwalks, there is much less private info to hide.

Let me know, thanks.

pyron83 commented 1 year ago

@pyron83 by the way, if this is solved in testing and the bug doesn't warrant a fix in bullseye (or that takes too long), I'm willing to support cacti again in backports. Would that help you?

thanks for your interest @paulgevers

I'll let you know how goes with debugging with @netniV and let you know.

pyron83 commented 1 year ago

waiting for @netniV reply, thanks

netniV commented 1 year ago

Sorry, been off ill, and now it's Christmas so might be a delay.

pyron83 commented 1 year ago

Sorry, been off ill, and now it's Christmas so might be a delay.

Let's update the issue after the holidays then. Merry Christmas.

pyron83 commented 1 year ago

hi @netniV when you want, I'm ready to send you a full snmpwalk or a snmpwalk of the script OIDs

thanks

Luth1ng commented 1 year ago

Sorry for my late reply @netniV. If you look at the diff between last and current version, you'll see there is no change of the OID : https://github.com/netniV/cisco-sfp/compare/0.2.5...0.3.0 I only updated deprecated php basic fonctions like "ereg_replace". The current script version is working on my 3750 switches.

@pyron83, can you provide output of these commands : NB: be sure to replace '169' number by the host ID of the device you're polling

snmpwalk -v2c -c mycommunity myhost.domain.com 1.3.6.1.2.1.47.1.1.1.1.2
snmpwalk -v2c -c mycommunity myhost.domain.com 1.3.6.1.4.1.9.9.91.1.1.1.1.1
snmpwalk -v2c -c mycommunity myhost.domain.com 1.3.6.1.4.1.9.9.91.1.1.1.1.4
snmpwalk -v2c -c mycommunity myhost.domain.com 1.3.6.1.4.1.9.9.91.1.1.1.1.5

"/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'index'

"/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'status'

"/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr'

"/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'interface'

"/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex'

/usr/bin/php -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex' | awk -F ':' '{print $2}' | xargs -I{} /usr/bin/php -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' "{}";

/usr/bin/php -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex' | awk -F ':' '{print $2}' | xargs -I{} /usr/bin/php -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' "{}";
pyron83 commented 1 year ago

snmpwalk content:

myuser@myserver:~$ cat snmpwalk1
.1.3.6.1.2.1.47.1.1.1.1.2.1 = STRING: "c38xx Stack"
.1.3.6.1.2.1.47.1.1.1.1.2.1000 = STRING: "WS-C3850-24S-E"
.1.3.6.1.2.1.47.1.1.1.1.2.1001 = STRING: "StackPort1/1"
.1.3.6.1.2.1.47.1.1.1.1.2.1002 = STRING: "StackPort1/2"
.1.3.6.1.2.1.47.1.1.1.1.2.1006 = STRING: "Switch 1 - WS-C3850-24S - Power Supply A Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1007 = STRING: "Switch 1 - WS-C3850-24S - Power Supply B Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1008 = STRING: "Switch 1 - WS-C3850-24S - RPS Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1009 = STRING: "Switch 1 - WS-C3850-24S - Fan 1 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1010 = STRING: "Switch 1 - WS-C3850-24S - Fan 2 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1011 = STRING: "Switch 1 - WS-C3850-24S - Fan 3 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1012 = STRING: "Switch 1 - WS-C3850-24S - Temp Inlet Sensor 0"
.1.3.6.1.2.1.47.1.1.1.1.2.1013 = STRING: "Switch 1 - WS-C3850-24S - Temp Outlet Sensor 1"
.1.3.6.1.2.1.47.1.1.1.1.2.1014 = STRING: "Switch 1 - WS-C3850-24S - Temp HotSpot Sensor 2"
.1.3.6.1.2.1.47.1.1.1.1.2.1015 = STRING: "Switch 1 - Power Supply A"
.1.3.6.1.2.1.47.1.1.1.1.2.1016 = STRING: "Switch 1 - Power Supply B"
.1.3.6.1.2.1.47.1.1.1.1.2.1017 = STRING: "Switch 1 - WS-C3850-24S - FAN 1"
.1.3.6.1.2.1.47.1.1.1.1.2.1018 = STRING: "Switch 1 - WS-C3850-24S - FAN 2"
.1.3.6.1.2.1.47.1.1.1.1.2.1019 = STRING: "Switch 1 - WS-C3850-24S - FAN 3"
.1.3.6.1.2.1.47.1.1.1.1.2.1060 = STRING: "Switch 1 - WS-C3850-24S - Fixed Module 0"
.1.3.6.1.2.1.47.1.1.1.1.2.1061 = STRING: "Switch 1 Slot 1 FRULink Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1062 = STRING: "Gi1/0/1 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1063 = STRING: "Gi1/0/2 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1064 = STRING: "Gi1/0/3 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1065 = STRING: "Gi1/0/4 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1066 = STRING: "Gi1/0/5 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1067 = STRING: "Gi1/0/6 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1068 = STRING: "Gi1/0/7 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1069 = STRING: "Gi1/0/8 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1070 = STRING: "Gi1/0/9 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1071 = STRING: "Gi1/0/10 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1072 = STRING: "Gi1/0/11 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1073 = STRING: "Gi1/0/12 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1074 = STRING: "Gi1/0/13 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1075 = STRING: "Gi1/0/14 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1076 = STRING: "Gi1/0/15 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1077 = STRING: "Gi1/0/16 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1078 = STRING: "Gi1/0/17 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1079 = STRING: "Gi1/0/18 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1080 = STRING: "Gi1/0/19 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1081 = STRING: "Gi1/0/20 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1082 = STRING: "Gi1/0/21 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1083 = STRING: "Gi1/0/22 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1084 = STRING: "Gi1/0/23 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1085 = STRING: "Gi1/0/24 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1086 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1087 = STRING: "GigabitEthernet1/0/1 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1088 = STRING: "GigabitEthernet1/0/1 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1089 = STRING: "GigabitEthernet1/0/1 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1090 = STRING: "GigabitEthernet1/0/1 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1091 = STRING: "GigabitEthernet1/0/1 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1092 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1093 = STRING: "GigabitEthernet1/0/2 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1094 = STRING: "GigabitEthernet1/0/2 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1095 = STRING: "GigabitEthernet1/0/2 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1096 = STRING: "GigabitEthernet1/0/2 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1097 = STRING: "GigabitEthernet1/0/2 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1098 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1099 = STRING: "GigabitEthernet1/0/3 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1100 = STRING: "GigabitEthernet1/0/3 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1101 = STRING: "GigabitEthernet1/0/3 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1102 = STRING: "GigabitEthernet1/0/3 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1103 = STRING: "GigabitEthernet1/0/3 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1104 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1105 = STRING: "GigabitEthernet1/0/7 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1106 = STRING: "GigabitEthernet1/0/7 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1107 = STRING: "GigabitEthernet1/0/7 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1108 = STRING: "GigabitEthernet1/0/7 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1109 = STRING: "GigabitEthernet1/0/7 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1110 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1111 = STRING: "GigabitEthernet1/0/8 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1112 = STRING: "GigabitEthernet1/0/8 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1113 = STRING: "GigabitEthernet1/0/8 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1114 = STRING: "GigabitEthernet1/0/8 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1115 = STRING: "GigabitEthernet1/0/8 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1116 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1117 = STRING: "GigabitEthernet1/0/9 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1118 = STRING: "GigabitEthernet1/0/9 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1119 = STRING: "GigabitEthernet1/0/9 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1120 = STRING: "GigabitEthernet1/0/9 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1121 = STRING: "GigabitEthernet1/0/9 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1122 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1123 = STRING: "GigabitEthernet1/0/10 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1124 = STRING: "GigabitEthernet1/0/10 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1125 = STRING: "GigabitEthernet1/0/10 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1126 = STRING: "GigabitEthernet1/0/10 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1127 = STRING: "GigabitEthernet1/0/10 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1128 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1129 = STRING: "GigabitEthernet1/0/11 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1130 = STRING: "GigabitEthernet1/0/11 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1131 = STRING: "GigabitEthernet1/0/11 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1132 = STRING: "GigabitEthernet1/0/11 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1133 = STRING: "GigabitEthernet1/0/11 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1134 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1135 = STRING: "GigabitEthernet1/0/15 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1136 = STRING: "GigabitEthernet1/0/15 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1137 = STRING: "GigabitEthernet1/0/15 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1138 = STRING: "GigabitEthernet1/0/15 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1139 = STRING: "GigabitEthernet1/0/15 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1140 = STRING: "10/100/1000BaseTX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1141 = STRING: "1000BaseZX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.1142 = STRING: "GigabitEthernet1/0/24 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1143 = STRING: "GigabitEthernet1/0/24 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1144 = STRING: "GigabitEthernet1/0/24 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1145 = STRING: "GigabitEthernet1/0/24 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1146 = STRING: "GigabitEthernet1/0/24 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1147 = STRING: "2x1G 2x10G Uplink Module"
.1.3.6.1.2.1.47.1.1.1.1.2.1148 = STRING: "Gi1/1/1 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.1149 = STRING: "SFP-10GBase-ZR"
.1.3.6.1.2.1.47.1.1.1.1.2.1150 = STRING: "TenGigabitEthernet1/1/3 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1151 = STRING: "TenGigabitEthernet1/1/3 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1152 = STRING: "TenGigabitEthernet1/1/3 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1153 = STRING: "TenGigabitEthernet1/1/3 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.1154 = STRING: "TenGigabitEthernet1/1/3 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2000 = STRING: "WS-C3850-24S-E"
.1.3.6.1.2.1.47.1.1.1.1.2.2001 = STRING: "StackPort2/1"
.1.3.6.1.2.1.47.1.1.1.1.2.2002 = STRING: "StackPort2/2"
.1.3.6.1.2.1.47.1.1.1.1.2.2006 = STRING: "Switch 2 - WS-C3850-24S - Power Supply A Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2007 = STRING: "Switch 2 - WS-C3850-24S - Power Supply B Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2008 = STRING: "Switch 2 - WS-C3850-24S - RPS Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2009 = STRING: "Switch 2 - WS-C3850-24S - Fan 1 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2010 = STRING: "Switch 2 - WS-C3850-24S - Fan 2 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2011 = STRING: "Switch 2 - WS-C3850-24S - Fan 3 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2012 = STRING: "Switch 2 - WS-C3850-24S - Temp Inlet Sensor 0"
.1.3.6.1.2.1.47.1.1.1.1.2.2013 = STRING: "Switch 2 - WS-C3850-24S - Temp Outlet Sensor 1"
.1.3.6.1.2.1.47.1.1.1.1.2.2014 = STRING: "Switch 2 - WS-C3850-24S - Temp HotSpot Sensor 2"
.1.3.6.1.2.1.47.1.1.1.1.2.2015 = STRING: "Switch 2 - Power Supply A"
.1.3.6.1.2.1.47.1.1.1.1.2.2016 = STRING: "Switch 2 - Power Supply B"
.1.3.6.1.2.1.47.1.1.1.1.2.2017 = STRING: "Switch 2 - WS-C3850-24S - FAN 1"
.1.3.6.1.2.1.47.1.1.1.1.2.2018 = STRING: "Switch 2 - WS-C3850-24S - FAN 2"
.1.3.6.1.2.1.47.1.1.1.1.2.2019 = STRING: "Switch 2 - WS-C3850-24S - FAN 3"
.1.3.6.1.2.1.47.1.1.1.1.2.2060 = STRING: "Switch 2 - WS-C3850-24S - Fixed Module 0"
.1.3.6.1.2.1.47.1.1.1.1.2.2061 = STRING: "Switch 2 Slot 1 FRULink Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2062 = STRING: "Gi2/0/1 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2063 = STRING: "Gi2/0/2 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2064 = STRING: "Gi2/0/3 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2065 = STRING: "Gi2/0/4 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2066 = STRING: "Gi2/0/5 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2067 = STRING: "Gi2/0/6 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2068 = STRING: "Gi2/0/7 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2069 = STRING: "Gi2/0/8 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2070 = STRING: "Gi2/0/9 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2071 = STRING: "Gi2/0/10 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2072 = STRING: "Gi2/0/11 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2073 = STRING: "Gi2/0/12 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2074 = STRING: "Gi2/0/13 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2075 = STRING: "Gi2/0/14 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2076 = STRING: "Gi2/0/15 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2077 = STRING: "Gi2/0/16 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2078 = STRING: "Gi2/0/17 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2079 = STRING: "Gi2/0/18 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2080 = STRING: "Gi2/0/19 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2081 = STRING: "Gi2/0/20 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2082 = STRING: "Gi2/0/21 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2083 = STRING: "Gi2/0/22 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2084 = STRING: "Gi2/0/23 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2085 = STRING: "Gi2/0/24 Container"
.1.3.6.1.2.1.47.1.1.1.1.2.2086 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2087 = STRING: "GigabitEthernet2/0/1 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2088 = STRING: "GigabitEthernet2/0/1 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2089 = STRING: "GigabitEthernet2/0/1 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2090 = STRING: "GigabitEthernet2/0/1 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2091 = STRING: "GigabitEthernet2/0/1 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2092 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2093 = STRING: "GigabitEthernet2/0/2 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2094 = STRING: "GigabitEthernet2/0/2 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2095 = STRING: "GigabitEthernet2/0/2 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2096 = STRING: "GigabitEthernet2/0/2 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2097 = STRING: "GigabitEthernet2/0/2 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2098 = STRING: "1000BaseSX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2099 = STRING: "GigabitEthernet2/0/3 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2100 = STRING: "GigabitEthernet2/0/3 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2101 = STRING: "GigabitEthernet2/0/3 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2102 = STRING: "GigabitEthernet2/0/3 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2103 = STRING: "GigabitEthernet2/0/3 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2104 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2105 = STRING: "GigabitEthernet2/0/13 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2106 = STRING: "GigabitEthernet2/0/13 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2107 = STRING: "GigabitEthernet2/0/13 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2108 = STRING: "GigabitEthernet2/0/13 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2109 = STRING: "GigabitEthernet2/0/13 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2110 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2111 = STRING: "GigabitEthernet2/0/14 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2112 = STRING: "GigabitEthernet2/0/14 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2113 = STRING: "GigabitEthernet2/0/14 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2114 = STRING: "GigabitEthernet2/0/14 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2115 = STRING: "GigabitEthernet2/0/14 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2116 = STRING: "1000BaseLX SFP"
.1.3.6.1.2.1.47.1.1.1.1.2.2117 = STRING: "GigabitEthernet2/0/15 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2118 = STRING: "GigabitEthernet2/0/15 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2119 = STRING: "GigabitEthernet2/0/15 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2120 = STRING: "GigabitEthernet2/0/15 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2121 = STRING: "GigabitEthernet2/0/15 Receive Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2122 = STRING: "2x1G 2x10G Uplink Module"
.1.3.6.1.2.1.47.1.1.1.1.2.2123 = STRING: "SFP-10GBase-LR"
.1.3.6.1.2.1.47.1.1.1.1.2.2124 = STRING: "TenGigabitEthernet2/1/3 Module Temperature Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2125 = STRING: "TenGigabitEthernet2/1/3 Supply Voltage Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2126 = STRING: "TenGigabitEthernet2/1/3 Bias Current Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2127 = STRING: "TenGigabitEthernet2/1/3 Transmit Power Sensor"
.1.3.6.1.2.1.47.1.1.1.1.2.2128 = STRING: "TenGigabitEthernet2/1/3 Receive Power Sensor"
myuser@myserver:~$ cat snmpwalk2
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1012 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1013 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1014 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1087 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1088 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1089 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1090 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1091 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1093 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1094 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1095 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1096 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1097 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1099 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1100 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1101 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1102 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1103 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1105 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1106 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1107 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1108 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1109 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1111 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1112 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1113 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1114 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1115 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1117 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1118 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1119 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1120 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1121 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1123 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1124 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1125 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1126 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1127 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1129 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1130 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1131 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1132 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1133 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1135 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1136 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1137 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1138 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1139 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1142 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1143 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1144 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1145 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1146 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1150 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1151 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1152 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1153 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.1154 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2012 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2013 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2014 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2087 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2088 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2089 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2090 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2091 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2093 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2094 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2095 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2096 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2097 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2099 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2100 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2101 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2102 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2103 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2105 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2106 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2107 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2108 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2109 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2111 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2112 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2113 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2114 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2115 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2117 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2118 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2119 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2120 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2121 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2124 = INTEGER: 8
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2125 = INTEGER: 4
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2126 = INTEGER: 5
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2127 = INTEGER: 14
.1.3.6.1.4.1.9.9.91.1.1.1.1.1.2128 = INTEGER: 14
myuser@myserver:~$ cat snmpwalk3
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1012 = INTEGER: 24
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1013 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1014 = INTEGER: 36
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1087 = INTEGER: 261
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1088 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1089 = INTEGER: 42
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1090 = INTEGER: -57
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1091 = INTEGER: -64
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1093 = INTEGER: 287
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1094 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1095 = INTEGER: 53
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1096 = INTEGER: -56
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1097 = INTEGER: -84
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1099 = INTEGER: 268
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1100 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1101 = INTEGER: 51
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1102 = INTEGER: -56
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1103 = INTEGER: -78
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1105 = INTEGER: 298
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1106 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1107 = INTEGER: 134
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1108 = INTEGER: -71
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1109 = INTEGER: -216
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1111 = INTEGER: 276
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1112 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1113 = INTEGER: 142
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1114 = INTEGER: -70
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1115 = INTEGER: -98
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1117 = INTEGER: 303
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1118 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1119 = INTEGER: 164
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1120 = INTEGER: -70
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1121 = INTEGER: -399
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1123 = INTEGER: 309
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1124 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1125 = INTEGER: 143
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1126 = INTEGER: -72
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1127 = INTEGER: -299
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1129 = INTEGER: 289
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1130 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1131 = INTEGER: 150
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1132 = INTEGER: -71
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1133 = INTEGER: -399
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1135 = INTEGER: 209
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1136 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1137 = INTEGER: 0
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1138 = INTEGER: 0
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1139 = INTEGER: 0
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1142 = INTEGER: 388
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1143 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1144 = INTEGER: 239
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1145 = INTEGER: 29
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1146 = INTEGER: -315
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1150 = INTEGER: 182
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1151 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1152 = INTEGER: 792
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1153 = INTEGER: 6
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.1154 = INTEGER: -196
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2012 = INTEGER: 23
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2013 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2014 = INTEGER: 38
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2087 = INTEGER: 281
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2088 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2089 = INTEGER: 49
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2090 = INTEGER: -56
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2091 = INTEGER: -99
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2093 = INTEGER: 275
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2094 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2095 = INTEGER: 50
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2096 = INTEGER: -56
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2097 = INTEGER: -79
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2099 = INTEGER: 271
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2100 = INTEGER: 33
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2101 = INTEGER: 42
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2102 = INTEGER: -56
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2103 = INTEGER: -92
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2105 = INTEGER: 256
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2106 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2107 = INTEGER: 131
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2108 = INTEGER: -71
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2109 = INTEGER: -92
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2111 = INTEGER: 269
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2112 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2113 = INTEGER: 139
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2114 = INTEGER: -71
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2115 = INTEGER: -157
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2117 = INTEGER: 261
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2118 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2119 = INTEGER: 144
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2120 = INTEGER: -70
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2121 = INTEGER: -100
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2124 = INTEGER: 230
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2125 = INTEGER: 32
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2126 = INTEGER: 380
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2127 = INTEGER: -23
.1.3.6.1.4.1.9.9.91.1.1.1.1.4.2128 = INTEGER: -18
myuser@myserver:~$ cat snmpwalk4
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1012 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1013 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1014 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1087 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1088 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1089 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1090 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1091 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1093 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1094 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1095 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1096 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1097 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1099 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1100 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1101 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1102 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1103 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1105 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1106 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1107 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1108 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1109 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1111 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1112 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1113 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1114 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1115 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1117 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1118 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1119 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1120 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1121 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1123 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1124 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1125 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1126 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1127 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1129 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1130 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1131 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1132 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1133 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1135 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1136 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1137 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1138 = INTEGER: 2
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1139 = INTEGER: 2
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1142 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1143 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1144 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1145 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1146 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1150 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1151 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1152 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1153 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.1154 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2012 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2013 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2014 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2087 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2088 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2089 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2090 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2091 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2093 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2094 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2095 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2096 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2097 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2099 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2100 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2101 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2102 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2103 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2105 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2106 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2107 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2108 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2109 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2111 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2112 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2113 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2114 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2115 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2117 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2118 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2119 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2120 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2121 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2124 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2125 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2126 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2127 = INTEGER: 1
.1.3.6.1.4.1.9.9.91.1.1.1.1.5.2128 = INTEGER: 1
myuser@myserver:~$
pyron83 commented 1 year ago

php content

myuser@myserver:/home/myuser# cat php1
1090
1096
1102
1108
1114
1120
1126
1132
1138
1145
1153
2090
2096
2102
2108
2114
2120
2127
myuser@myserver:/home/myuser# cat php2
1090:TX Online / RX Online
1096:TX Online / RX Online
1102:TX Online / RX Online
1108:TX Online / RX Online
1114:TX Online / RX Online
1120:TX Online / RX Online
1126:TX Online / RX Online
1132:TX Online / RX Online
1138:TX Failure / RX Failure
1145:TX Online / RX Online
1153:TX Online / RX Online
2090:TX Online / RX Online
2096:TX Online / RX Online
2102:TX Online / RX Online
2108:TX Online / RX Online
2114:TX Online / RX Online
2120:TX Online / RX Online
2127:TX Online / RX Online
myuser@myserver:/home/myuser# cat php3
1090:
1096:
1102:
1108:
1114:
1120:
1126:
1132:
1138:
1145:
1153:
2090:
2096:
2102:
2108:
2114:
2120:
2127:
myuser@myserver:/home/myuser# cat php4
1090:
1096:
1102:
1108:
1114:
1120:
1126:
1132:
1138:
1145:
1153:
2090:
2096:
2102:
2108:
2114:
2120:
2127:
myuser@myserver:/home/myuser# cat php5
1090:1090
1096:1096
1102:1102
1108:1108
1114:1114
1120:1120
1126:1126
1132:1132
1138:1138
1145:1145
1153:1153
2090:2090
2096:2096
2102:2102
2108:2108
2114:2114
2120:2120
2127:2127
myuser@myserver:/home/myuser# cat php6
-6.4-8.4-7.8-21.6-9.8-39.9-29.9-39.9-40-30.9-19.3-11.1-7.9-9.3-9.2-15.6-10-1.8
myuser@myserver:/home/myuser# cat php7
-5.7-5.6-5.6-7.1-7-7.1-7.2-7.1-402.90.6-5.6-5.6-5.7-7-7-7.1-2.3
myuser@myserver:/home/myuser#
Luth1ng commented 1 year ago

@pyron83 it seems you cannot get cacti data from mysql db_fetch_cell function. Can you try the attached debug file ? ss_cisco_catalyst_sfp_querydescrdbg.php.txt

You can execute the script from any directory as long as you replace include lines with correct path.

Just provide output of query descr cmd please ("cat php3")

pyron83 commented 1 year ago

mumble is it normal to only have few lines of output on stdout?


:~$ sudo php ss_cisco_catalyst_sfp_querydescrdbg.php
[sudo] password for myuser:

---Debug enabled for query descr command---
:~$
Luth1ng commented 1 year ago

I wasn't clear sorry, you need to use the script as the original, like : "/usr/bin/php" -q /usr/share/cacti/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myhost.domain.com:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr'

Also, double check the three "include" lines in the script, and be sure the path is correct :

include_once("/usr/share/cacti/include/config.php");
include_once("/usr/share/cacti/include/global.php");
include_once("/usr/share/cacti/lib/snmp.php");
pyron83 commented 1 year ago

Yes sorry, I figured it out a little later even if it was obvious (I gave a look at the script). My mistake. I'm preparing the output i'll give it to you asap. Thanks.

pyron83 commented 1 year ago

root@myserver:/home/myuser# "/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'index' > php1; cat php1
"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'status' > php2; cat php2
"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr'  > php3; cat php3
"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'interface'  > php4; cat php4
"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex'  > php5; cat php5

---Debug enabled for query descr command---
1090
1096
1102
1108
1114
1120
1126
1132
1138
1145
1153
2090
2096
2102
2108
2114
2120
2127

---Debug enabled for query descr command---
1090:TX Online / RX Online
1096:TX Online / RX Online
1102:TX Online / RX Online
1108:TX Online / RX Online
1114:TX Online / RX Online
1120:TX Online / RX Online
1126:TX Online / RX Online
1132:TX Online / RX Online
1138:TX Failure / RX Failure
1145:TX Online / RX Online
1153:TX Online / RX Online
2090:TX Online / RX Online
2096:TX Online / RX Online
2102:TX Online / RX Online
2108:TX Online / RX Online
2114:TX Online / RX Online
2120:TX Online / RX Online
2127:TX Online / RX Online

---Debug enabled for query descr command---

----------

DBG1_sensor_name:GigabitEthernet1/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1090
1090:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1096
1096:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1102
1102:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/7 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1108
1108:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/8 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1114
1114:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/9 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1120
1120:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/10 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1126
1126:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/11 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1132
1132:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1138
1138:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/24 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1145
1145:

----------

----------

DBG1_sensor_name:TenGigabitEthernet1/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1153
1153:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2090
2090:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2096
2096:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2102
2102:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/13 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2108
2108:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/14 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2114
2114:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2120
2120:

----------

----------

DBG1_sensor_name:TenGigabitEthernet2/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2127
2127:

----------

---Debug enabled for query descr command---
1090:
1096:
1102:
1108:
1114:
1120:
1126:
1132:
1138:
1145:
1153:
2090:
2096:
2102:
2108:
2114:
2120:
2127:

---Debug enabled for query descr command---
1090:1090
1096:1096
1102:1102
1108:1108
1114:1114
1120:1120
1126:1126
1132:1132
1138:1138
1145:1145
1153:1153
2090:2090
2096:2096
2102:2102
2108:2108
2114:2114
2120:2120
2127:2127
root@myserver/home/myuser# /usr/bin/php -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex' | awk -F ':' '{print $2}' | xargs -I{} /usr/bin/php -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'get' 'rx' "{}"; 

---Debug enabled for query descr command---
-6.4
---Debug enabled for query descr command---
-8.3
---Debug enabled for query descr command---
-7.8
---Debug enabled for query descr command---
-21.6
---Debug enabled for query descr command---
-9.8
---Debug enabled for query descr command---
-39.9
---Debug enabled for query descr command---
-29.9
---Debug enabled for query descr command---
-39.9
---Debug enabled for query descr command---
-40
---Debug enabled for query descr command---
-31.5
---Debug enabled for query descr command---
-19.7
---Debug enabled for query descr command---
-9.9
---Debug enabled for query descr command---
-7.9
---Debug enabled for query descr command---
-9.3
---Debug enabled for query descr command---
-9.2
---Debug enabled for query descr command---
-15.7
---Debug enabled for query descr command---
-10.1
---Debug enabled for query descr command---
-1.8root@myserver/home/myuser# /usr/bin/php -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'sfpindex' | awk -F ':' '{print $2}' | xargs -I{} /usr/bin/php -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'get' 'tx' "{}"; 

---Debug enabled for query descr command---
-5.7
---Debug enabled for query descr command---
-5.6
---Debug enabled for query descr command---
-5.6
---Debug enabled for query descr command---
-7
---Debug enabled for query descr command---
-7
---Debug enabled for query descr command---
-7.1
---Debug enabled for query descr command---
-7.2
---Debug enabled for query descr command---
-7.2
---Debug enabled for query descr command---
-40
---Debug enabled for query descr command---
2.9
---Debug enabled for query descr command---
0.6
---Debug enabled for query descr command---
-5.6
---Debug enabled for query descr command---
-5.6
---Debug enabled for query descr command---
-5.7
---Debug enabled for query descr command---
-7.1
---Debug enabled for query descr command---
-7.1
---Debug enabled for query descr command---
-7.1
---Debug enabled for query descr command---
Luth1ng commented 1 year ago

Well that's what I thought, the script cannot get data stored in the cacti DB through MySQL.

The last two outputs you sent show the RX and TX dBm for all your supported interfaces with valid values. You just don't have the details about the interface. So the script seems to work.

We now will need to understand why the db_fetch_cell function is not getting value at all.

Can you try to run the DB analysis script ? /usr/bin/php -q /usr/share/cacti/cli/analyze_database.php -d

pyron83 commented 1 year ago

 /usr/bin/php -q /usr/share/cacti/cli/analyze_database.php -d
Analyzing All Cacti Database Tables
Analyzing Table -> 'aggregate_graph_templates' Successful
Analyzing Table -> 'aggregate_graph_templates_graph' Successful
Analyzing Table -> 'aggregate_graph_templates_item' Successful
Analyzing Table -> 'aggregate_graphs' Successful
Analyzing Table -> 'aggregate_graphs_graph_item' Successful
Analyzing Table -> 'aggregate_graphs_items' Successful
Analyzing Table -> 'automation_devices' Successful
Analyzing Table -> 'automation_graph_rule_items' Successful
Analyzing Table -> 'automation_graph_rules' Successful
Analyzing Table -> 'automation_ips' Successful
Analyzing Table -> 'automation_match_rule_items' Successful
Analyzing Table -> 'automation_networks' Successful
Analyzing Table -> 'automation_processes' Successful
Analyzing Table -> 'automation_snmp' Successful
Analyzing Table -> 'automation_snmp_items' Successful
Analyzing Table -> 'automation_templates' Successful
Analyzing Table -> 'automation_tree_rule_items' Successful
Analyzing Table -> 'automation_tree_rules' Successful
Analyzing Table -> 'cdef' Successful
Analyzing Table -> 'cdef_items' Successful
Analyzing Table -> 'color_template_items' Successful
Analyzing Table -> 'color_templates' Successful
Analyzing Table -> 'colors' Successful
Analyzing Table -> 'data_debug' Successful
Analyzing Table -> 'data_input' Successful
Analyzing Table -> 'data_input_data' Successful
Analyzing Table -> 'data_input_fields' Successful
Analyzing Table -> 'data_local' Successful
Analyzing Table -> 'data_source_profiles' Successful
Analyzing Table -> 'data_source_profiles_cf' Successful
Analyzing Table -> 'data_source_profiles_rra' Successful
Analyzing Table -> 'data_source_purge_action' Successful
Analyzing Table -> 'data_source_purge_temp' Successful
Analyzing Table -> 'data_source_stats_daily' Successful
Analyzing Table -> 'data_source_stats_hourly' Successful
Analyzing Table -> 'data_source_stats_hourly_cache' Successful
Analyzing Table -> 'data_source_stats_hourly_last' Successful
Analyzing Table -> 'data_source_stats_monthly' Successful
Analyzing Table -> 'data_source_stats_weekly' Successful
Analyzing Table -> 'data_source_stats_yearly' Successful
Analyzing Table -> 'data_template' Successful
Analyzing Table -> 'data_template_data' Successful
Analyzing Table -> 'data_template_rrd' Successful
Analyzing Table -> 'external_links' Successful
Analyzing Table -> 'graph_local' Successful
Analyzing Table -> 'graph_template_input' Successful
Analyzing Table -> 'graph_template_input_defs' Successful
Analyzing Table -> 'graph_templates' Successful
Analyzing Table -> 'graph_templates_gprint' Successful
Analyzing Table -> 'graph_templates_graph' Successful
Analyzing Table -> 'graph_templates_item' Successful
Analyzing Table -> 'graph_tree' Successful
Analyzing Table -> 'graph_tree_items' Successful
Analyzing Table -> 'host' Successful
Analyzing Table -> 'host_graph' Successful
Analyzing Table -> 'host_snmp_cache' Successful
Analyzing Table -> 'host_snmp_query' Successful
Analyzing Table -> 'host_template' Successful
Analyzing Table -> 'host_template_graph' Successful
Analyzing Table -> 'host_template_snmp_query' Successful
Analyzing Table -> 'mac_track_aggregated_ports' Successful
Analyzing Table -> 'mac_track_approved_macs' Successful
Analyzing Table -> 'mac_track_device_types' Successful
Analyzing Table -> 'mac_track_devices' Successful
Analyzing Table -> 'mac_track_interface_graphs' Successful
Analyzing Table -> 'mac_track_interfaces' Successful
Analyzing Table -> 'mac_track_ip_ranges' Successful
Analyzing Table -> 'mac_track_ips' Successful
Analyzing Table -> 'mac_track_macauth' Successful
Analyzing Table -> 'mac_track_macwatch' Successful
Analyzing Table -> 'mac_track_oui_database' Successful
Analyzing Table -> 'mac_track_ports' Successful
Analyzing Table -> 'mac_track_processes' Successful
Analyzing Table -> 'mac_track_scan_dates' Successful
Analyzing Table -> 'mac_track_scanning_functions' Successful
Analyzing Table -> 'mac_track_sites' Successful
Analyzing Table -> 'mac_track_snmp' Successful
Analyzing Table -> 'mac_track_snmp_items' Successful
Analyzing Table -> 'mac_track_temp_ports' Successful
Analyzing Table -> 'mac_track_vlans' Successful
Analyzing Table -> 'note' Successful
Analyzing Table -> 'plugin_config' Successful
Analyzing Table -> 'plugin_db_changes' Successful
Analyzing Table -> 'plugin_docs' Successful
Analyzing Table -> 'plugin_fix64bit' Successful
Analyzing Table -> 'plugin_hooks' Successful
Analyzing Table -> 'plugin_notification_lists' Successful
Analyzing Table -> 'plugin_realms' Successful
Analyzing Table -> 'plugin_routerconfigs_accounts' Successful
Analyzing Table -> 'plugin_routerconfigs_backups' Successful
Analyzing Table -> 'plugin_routerconfigs_devices' Successful
Analyzing Table -> 'plugin_routerconfigs_devicetypes' Successful
Analyzing Table -> 'plugin_thold_contacts' Successful
Analyzing Table -> 'plugin_thold_daemon_data' Successful
Analyzing Table -> 'plugin_thold_daemon_processes' Successful
Analyzing Table -> 'plugin_thold_host_failed' Successful
Analyzing Table -> 'plugin_thold_host_template' Successful
Analyzing Table -> 'plugin_thold_log' Successful
Analyzing Table -> 'plugin_thold_template_contact' Successful
Analyzing Table -> 'plugin_thold_threshold_contact' Successful
Analyzing Table -> 'plugin_update_info' Successful
Analyzing Table -> 'poller' Successful
Analyzing Table -> 'poller_command' Successful
Analyzing Table -> 'poller_data_template_field_mappings' Successful
Analyzing Table -> 'poller_item' Successful
Analyzing Table -> 'poller_output' Successful
Analyzing Table -> 'poller_output_boost' Successful
Analyzing Table -> 'poller_output_boost_processes' Successful
Analyzing Table -> 'poller_output_realtime' Successful
Analyzing Table -> 'poller_reindex' Successful
Analyzing Table -> 'poller_resource_cache' Successful
Analyzing Table -> 'poller_time' Successful
Analyzing Table -> 'processes' Successful
Analyzing Table -> 'reportit_cache_measurands' Successful
Analyzing Table -> 'reportit_cache_reports' Successful
Analyzing Table -> 'reportit_cache_variables' Successful
Analyzing Table -> 'reportit_measurands' Successful
Analyzing Table -> 'reportit_presets' Successful
Analyzing Table -> 'reportit_recipients' Successful
Analyzing Table -> 'reportit_reports' Successful
Analyzing Table -> 'reportit_rvars' Successful
Analyzing Table -> 'reportit_templates' Successful
Analyzing Table -> 'reportit_variables' Successful
Analyzing Table -> 'reports' Successful
Analyzing Table -> 'reports_items' Successful
Analyzing Table -> 'sessions' Successful
Analyzing Table -> 'settings' Successful
Analyzing Table -> 'settings_tree' Successful
Analyzing Table -> 'settings_user' Successful
Analyzing Table -> 'settings_user_group' Successful
Analyzing Table -> 'sites' Successful
Analyzing Table -> 'snmp_query' Successful
Analyzing Table -> 'snmp_query_graph' Successful
Analyzing Table -> 'snmp_query_graph_rrd' Successful
Analyzing Table -> 'snmp_query_graph_rrd_sv' Successful
Analyzing Table -> 'snmp_query_graph_sv' Successful
Analyzing Table -> 'snmpagent_cache' Successful
Analyzing Table -> 'snmpagent_cache_notifications' Successful
Analyzing Table -> 'snmpagent_cache_textual_conventions' Successful
Analyzing Table -> 'snmpagent_managers' Successful
Analyzing Table -> 'snmpagent_managers_notifications' Successful
Analyzing Table -> 'snmpagent_mibs' Successful
Analyzing Table -> 'snmpagent_notifications_log' Successful
Analyzing Table -> 'thold_data' Successful
Analyzing Table -> 'thold_template' Successful
Analyzing Table -> 'user_auth' Successful
Analyzing Table -> 'user_auth_cache' Successful
Analyzing Table -> 'user_auth_group' Successful
Analyzing Table -> 'user_auth_group_members' Successful
Analyzing Table -> 'user_auth_group_perms' Successful
Analyzing Table -> 'user_auth_group_realm' Successful
Analyzing Table -> 'user_auth_perms' Successful
Analyzing Table -> 'user_auth_realm' Successful
Analyzing Table -> 'user_domains' Successful
Analyzing Table -> 'user_domains_ldap' Successful
Analyzing Table -> 'user_log' Successful
Analyzing Table -> 'vdef' Successful
Analyzing Table -> 'vdef_items' Successful
Analyzing Table -> 'version' Successful
Luth1ng commented 1 year ago

For debugging purpose:

Can you try adding this line :

        print "\nDBG101_sql:" . $sql;

At line 457 in /usr/share/cacti/lib/database.php. The function db_fetch_cell block should be like this :

function db_fetch_cell($sql, $col_name = '', $log = true, $db_conn = false) {
        global $config;
        print "\nDBG101_sql:" . $sql;
        if (!empty($config['DEBUG_SQL_FLOW'])) {
                db_echo_sql('db_fetch_cell($sql, $col_name = \'' . $col_name . '\', $log = true, $db_conn = false)' . "\n");
        }

        return db_fetch_cell_prepared($sql, array(), $col_name, $log, $db_conn);
}

Warning: this will break a lot of Cacti functions while the debug is active

Can you send the output of the command :

"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr'  > php3; cat php3

Remember to either comment or delete the line after you got the output

netniV commented 1 year ago

To avoid breaking the rest of cacti, you may want to set $config['DEBUG_SQL_FLOW'] to true from your script after calling the include()'s. This option will enable debug output of database calls. This will put the outputs into cacti-sql.log of the temp directory. You could manually change this by updating the location in the db_echo_sql() function. We should probably make the location also definable.

netniV commented 1 year ago

@Luth1ng thanks for getting back. It's never too late if it helps 👍 Appreciate the work you've done here. Hopefully, it's a nothing too complex.

pyron83 commented 1 year ago

I'm gonna do this test as soon as I can, I'll do a VM a snapshot before doing anything just to be safe. I'll keep you updated. Thanks

pyron83 commented 1 year ago

For debugging purpose:

Can you try adding this line :

        print "\nDBG101_sql:" . $sql;

At line 457 in /usr/share/cacti/lib/database.php. The function db_fetch_cell block should be like this :

function db_fetch_cell($sql, $col_name = '', $log = true, $db_conn = false) {
        global $config;
        print "\nDBG101_sql:" . $sql;
        if (!empty($config['DEBUG_SQL_FLOW'])) {
                db_echo_sql('db_fetch_cell($sql, $col_name = \'' . $col_name . '\', $log = true, $db_conn = false)' . "\n");
        }

        return db_fetch_cell_prepared($sql, array(), $col_name, $log, $db_conn);
}

Warning: this will break a lot of Cacti functions while the debug is active

Can you send the output of the command :

"/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr'  > php3; cat php3

Remember to either comment or delete the line after you got the output

looks like our file is different, if I put a line on 457 I've

function db_fetch_row_return($query) {
        global $config;

        if (!empty($config['DEBUG_SQL_FLOW'])) {
                db_echo_sql('db_fetch_row_return($query)' . "\n");
        }

#https://github.com/netniV/cisco-sfp/issues/10
print "\nDBG101_sql:" . $sql;

        if ($query->rowCount()) {
                $r = $query->fetchAll(PDO::FETCH_ASSOC);
        }

        return (isset($r[0])) ? $r[0] : array();
# dpkg -l | grep cacti
ii  cacti                              1.2.16+ds1-2+deb11u1                  all          web interface for graphing of monitoring systems
ii  cacti-spine                        1.2.16-1 
pyron83 commented 1 year ago

just for reference, this is the whole file:


# cat /usr/share/cacti/site/lib/database.php
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2004-2020 The Cacti Group                                 |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | Cacti: The Complete RRDtool-based Graphing Solution                     |
 +-------------------------------------------------------------------------+
 | This code is designed, written, and maintained by the Cacti Group. See  |
 | about.php and/or the AUTHORS file for specific developer information.   |
 +-------------------------------------------------------------------------+
 | http://www.cacti.net/                                                   |
 +-------------------------------------------------------------------------+
*/

/* db_connect_real - makes a connection to the database server
   @param $device - the hostname of the database server, 'localhost' if the database server is running
      on this machine
   @param $user - the username to connect to the database server as
   @param $pass - the password to connect to the database server with
   @param $db_name - the name of the database to connect to
   @param $db_type - the type of database server to connect to, only 'mysql' is currently supported
   @param $port - the port to communicate with MySQL/MariaDB on
   @param $retries - the number a time the server should attempt to connect before failing
   @param $db_ssl - boolean true or false
   @param $db_ssl_key - the client ssl key
   @param $db_ssl_cert - the client ssl cert
   @param $db_ssl_ca - the ssl ca
   @returns - (bool) '1' for success, '0' for error */
function db_connect_real($device, $user, $pass, $db_name, $db_type = 'mysql', $port = '3306', $retries = 20,
    $db_ssl = false, $db_ssl_key = '', $db_ssl_cert = '', $db_ssl_ca = '') {
    global $database_sessions, $database_total_queries, $config;
    $database_total_queries = 0;

    $i = 0;
    if (isset($database_sessions["$device:$port:$db_name"])) {
        return $database_sessions["$device:$port:$db_name"];
    }

    $odevice = $device;

    $flags = array();
    if ($db_type == 'mysql') {
        // Using 'localhost' will force unix sockets mode, which breaks when attempting to use mysql on a different port
        if ($device == 'localhost' && $port != '3306') {
            $device = '127.0.0.1';
        }

        if (!defined('PDO::MYSQL_ATTR_FOUND_ROWS')) {
            if (!empty($config['DEBUG_READ_CONFIG_OPTION'])) {
                $prefix = get_debug_prefix();
                file_put_contents(sys_get_temp_dir() . '/cacti-option.log', "$prefix\n$prefix ************* DATABASE MODULE MISSING ****************\n$prefix session name: $odevice:$port:$db_name\n$prefix\n", FILE_APPEND);
            }

            return false;
        }

        $flags[PDO::ATTR_PERSISTENT] = true;
        $flags[PDO::MYSQL_ATTR_FOUND_ROWS] = true;
        if ($db_ssl) {
            if ($db_ssl_key != '' && $db_ssl_cert != '' && $db_ssl_ca != '') {
                if (file_exists($db_ssl_key) && file_exists($db_ssl_cert) && file_exists($db_ssl_ca)) {
                    $flags[PDO::MYSQL_ATTR_SSL_KEY]  = $db_ssl_key;
                    $flags[PDO::MYSQL_ATTR_SSL_CERT] = $db_ssl_cert;
                    $flags[PDO::MYSQL_ATTR_SSL_CA]   = $db_ssl_ca;
                } elseif (file_exists($db_ssl_key) && file_exists($db_ssl_cert)) {
                    $flags[PDO::MYSQL_ATTR_SSL_KEY]  = $db_ssl_key;
                    $flags[PDO::MYSQL_ATTR_SSL_CERT] = $db_ssl_cert;
                }
            }
        }
    }

    while ($i <= $retries) {
        try {
            if (strpos($device, '/') !== false && filetype($device) == 'socket') {
                $cnn_id = new PDO("$db_type:unix_socket=$device;dbname=$db_name;charset=utf8", $user, $pass, $flags);
            } else {
                $cnn_id = new PDO("$db_type:host=$device;port=$port;dbname=$db_name;charset=utf8", $user, $pass, $flags);
            }
            $cnn_id->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);

            $bad_modes = array(
                'STRICT_TRANS_TABLES',
                'STRICT_ALL_TABLES',
                'TRADITIONAL',
                'NO_ZERO_DATE',
                'NO_ZERO_IN_DATE',
                'ONLY_FULL_GROUP_BY',
                'NO_AUTO_VALUE_ON_ZERO'
            );

            $database_sessions["$odevice:$port:$db_name"] = $cnn_id;

            $ver = db_get_global_variable('version', $cnn_id);

            if (strpos($ver, 'MariaDB') !== false) {
                $srv = 'MariaDB';
                $ver  = str_replace('-MariaDB', '', $ver);
            } else {
                $srv = 'MySQL';
            }

            if (version_compare('8.0.0', $ver, '<=')) {
                $bad_modes[] = 'NO_AUTO_CREATE_USER';
            }

            // Get rid of bad modes
            $modes = explode(',', db_fetch_cell('SELECT @@sql_mode', '', false));
            $new_modes = array();

            foreach($modes as $mode) {
                if (array_search($mode, $bad_modes) === false) {
                    $new_modes[] = $mode;
                }
            }

            // Add Required modes
            $required_modes[] = 'ALLOW_INVALID_DATES';
            $required_modes[] = 'NO_ENGINE_SUBSTITUTION';

            foreach($required_modes as $mode) {
                if (array_search($mode, $new_modes) === false) {
                    $new_modes[] = $mode;
                }
            }

            $sql_mode = implode(',', $new_modes);

            db_execute_prepared('SET SESSION sql_mode = ?', array($sql_mode), false);

            if (db_column_exists('poller', 'timezone')) {
                $timezone = db_fetch_cell_prepared('SELECT timezone
                    FROM poller
                    WHERE id = ?',
                    array($config['poller_id']), false);
            } else {
                $timezone = '';
            }

            if ($timezone != '') {
                db_execute_prepared('SET SESSION time_zone = ?', array($timezone), false);
            }

            if (!empty($config['DEBUG_READ_CONFIG_OPTION'])) {
                $prefix = get_debug_prefix();
                file_put_contents(sys_get_temp_dir() . '/cacti-option.log', "$prefix\n$prefix ************* DATABASE OPEN ****************\n$prefix session name: $odevice:$port:$db_name\n$prefix\n", FILE_APPEND);
            }

            if (!empty($config['DEBUG_READ_CONFIG_OPTION_DB_OPEN'])) {
                $config['DEBUG_READ_CONFIG_OPTION'] = false;
            }
            return $cnn_id;
        } catch (PDOException $e) {
            if (!isset($config['DATABASE_ERROR'])) {
                $config['DATABASE_ERROR'] = array();
            }

            $config['DATABASE_ERROR'][] = array(
                'Code' => $e->getCode(),
                'Error' => $e->getMessage(),
            );
            // Must catch this exception or else PDO will display an error with our username/password
            //print $e->getMessage();
            //exit;
        }

        $i++;
        usleep(40000);
    }

    return false;
}

function db_warning_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    throw new Exception($errstr, $errno);
}

/* db_close - closes the open connection
   @returns - the result of the close command */
function db_close($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $db_conn = null;
    $database_sessions["$database_hostname:$database_port:$database_default"] = null;

    return true;
}

/* db_execute - run an sql query and do not return any output
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - '1' for success, '0' for error */
function db_execute($sql, $log = true, $db_conn = false) {
    return db_execute_prepared($sql, array(), $log, $db_conn);
}

/* db_execute_prepared - run an sql query and do not return any output
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - '1' for success, '0' for error */
function db_execute_prepared($sql, $params = array(), $log = true, $db_conn = false, $execute_name = 'Exec', $default_value = true, $return_func = 'no_return_function', $return_params = array()) {
    global $database_sessions, $database_default, $config, $database_hostname, $database_port, $database_total_queries, $database_last_error, $database_log;
    $database_total_queries++;

    if (!isset($database_log)) {
        $database_log = false;
    }

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) {
            $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
        }

        if (!is_object($db_conn)) {
            $database_last_error = 'DB ' . $execute_name . ' -- No connection found';
            return false;
        }
    }

    $sql = db_strip_control_chars($sql);

    if (!empty($config['DEBUG_SQL_CMD'])) {
        db_echo_sql('db_' . $execute_name . ': "' . $sql . "\"\n");
    }

    $errors = 0;
    $db_conn->affected_rows = 0;

    while (true) {
        $query = $db_conn->prepare($sql);

        $code = 0;
        $en = '';

        if (!empty($config['DEBUG_SQL_CMD'])) {
            db_echo_sql('db_' . $execute_name . ' Memory [Before]: ' . memory_get_usage() . ' / ' . memory_get_peak_usage() . "\n");
        }

        set_error_handler('db_warning_handler',E_WARNING | E_NOTICE);
        try {
            if (empty($params) || cacti_count($params) == 0) {
                $query->execute();
            } else {
                $query->execute($params);
            }
        } catch (Exception $ex) {
            $code = $ex->getCode();
            $en = $code;
            $errorinfo = array(1=>$code, 2=>$ex->getMessage());
        }
        restore_error_handler();

        if (!empty($config['DEBUG_SQL_CMD'])) {
            db_echo_sql('db_' . $execute_name . ' Memory [ After]: ' . memory_get_usage() . ' / ' . memory_get_peak_usage() . "\n");
        }

        if ($code == 0) {
            $code = $query->errorCode();
            if ($code != '00000' && $code != '01000') {
                $errorinfo = $query->errorInfo();
                $en = $errorinfo[1];
            }  else {
                $code = $db_conn->errorCode();
                if ($code != '00000' && $code != '01000') {
                    $errorinfo = $db_conn->errorInfo();
                    $en = $errorinfo[1];
                }
            }
        }

        if ($en == '') {
            // With PDO, we have to free this up
            $db_conn->affected_rows = $query->rowCount();

            $return_value = $default_value;
            if (function_exists($return_func)) {
                $return_array = array($query);
                if (!empty($return_params)) {
                    if (!is_array($return_params)) {
                        $return_params = array($return_params);
                    }
                    $return_array = array_merge($return_array, $return_params);
                }

                if (!empty($config['DEBUG_SQL_FLOW'])) {
                    db_echo_sql('db_' . $execute_name . '_return_func: \'' . $return_func .'\' (' . function_exists($return_func) . ")\n");
                    db_echo_sql('db_' . $execute_name . '_return_func: params ' . clean_up_lines(var_export($return_array, true)) . "\n");
                }

                $return_value = call_user_func_array($return_func, $return_array);
            }
            $query->closeCursor();
            unset($query);

            if (!empty($config['DEBUG_SQL_FLOW'])) {
                db_echo_sql('db_' . $execute_name . ': returns ' . clean_up_lines(var_export($return_value, true)) . "\n", true);
            }
            return $return_value;
        } else {
            $database_last_error = 'DB ' . $execute_name . ' Failed!, Error ' . $en . ': ' . (isset($errorinfo[2]) ? $errorinfo[2] : '<no error>');
            if (isset($query)) {
                $query->closeCursor();
            }
            unset($query);

            if ($log) {
                if ($en == 1213 || $en == 1205) {
                    $errors++;
                    if ($errors > 30) {
                        cacti_log("ERROR: Too many Lock/Deadlock errors occurred! SQL:'" . clean_up_lines($sql) . "'", true, 'DBCALL', POLLER_VERBOSITY_DEBUG);
                        $database_last_error = "Too many Lock/Deadlock errors occurred!";
                    } else {
                        usleep(200000);

                        continue;
                    }
                } else if ($en == 1153) {
                    if (strlen($sql) > 1024) {
                        $sql = substr($sql, 0, 1024) . '...';
                    }

                    cacti_log('ERROR: A DB ' . $execute_name . ' Too Large!, Error: ' . $en . ', SQL: \'' . clean_up_lines($sql) . '\'', false, 'DBCALL', POLLER_VERBOSITY_DEBUG);
                    cacti_log('ERROR: A DB ' . $execute_name . ' Too Large!, Error: ' . $errorinfo[2], false, 'DBCALL', POLLER_VERBOSITY_DEBUG);
                    cacti_debug_backtrace('SQL', false, true, 0, 1);

                    $database_last_error = 'DB ' . $execute_name . ' Too Large!, Error ' . $en . ': ' . $errorinfo[2];
                } else {
                    cacti_log('ERROR: A DB ' . $execute_name . ' Failed!, Error: ' . $en . ', SQL: \'' . clean_up_lines($sql) . '\'', false, 'DBCALL', POLLER_VERBOSITY_DEBUG);
                    cacti_log('ERROR: A DB ' . $execute_name . ' Failed!, Error: ' . $errorinfo[2], false);
                    cacti_debug_backtrace('SQL', false, true, 0, 1);

                    $database_last_error = 'DB ' . $execute_name . ' Failed!, Error ' . $en . ': ' . (isset($errorinfo[2]) ? $errorinfo[2] : '<no error>');
                }
            }

            if (!empty($config['DEBUG_SQL_FLOW'])) {
                db_echo_sql($database_last_error);
            }
            return false;
        }
    }

    unset($query);

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql($database_last_error);
    }

    return false;
}

/* db_fetch_cell - run a 'select' sql query and return the first column of the
     first row found
   @param $sql - the sql query to execute
   @param $col_name - use this column name instead of the first one
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_fetch_cell($sql, $col_name = '', $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_cell($sql, $col_name = \'' . $col_name . '\', $log = true, $db_conn = false)' . "\n");
    }

    return db_fetch_cell_prepared($sql, array(), $col_name, $log, $db_conn);
}

/* db_fetch_cell_prepared - run a 'select' sql query and return the first column of the
     first row found
   @param $sql - the sql query to execute
   @param $col_name - use this column name instead of the first one
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_fetch_cell_prepared($sql, $params = array(), $col_name = '', $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_cell_prepared($sql, $params = ' . clean_up_lines(var_export($params, true)) . ', $col_name = \'' . $col_name . '\', $log = true, $db_conn = false)' . "\n");
    }

    return db_execute_prepared($sql, $params, $log, $db_conn, 'Cell', false, 'db_fetch_cell_return', $col_name);
}

function db_fetch_cell_return($query, $col_name = '') {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_cell_return($query, $col_name = \'' . $col_name . '\')' . "\n");
    }

    $r = $query->fetchAll(PDO::FETCH_BOTH);
    if (isset($r[0]) && is_array($r[0])) {
        if ($col_name != '') {
            return $r[0][$col_name];
        } else {
            return reset($r[0]);
        }
    }
    return false;
}

/* db_fetch_row - run a 'select' sql query and return the first row found
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - the first row of the result as a hash */
function db_fetch_row($sql, $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_row(\'' . clean_up_lines($sql) . '\', $log = ' . $log . ', $db_conn = ' . ($db_conn ? 'true' : 'false') .')' . "\n");
    }

    return db_fetch_row_prepared($sql, array(), $log, $db_conn);
}

/* db_fetch_row_prepared - run a 'select' sql query and return the first row found
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - the first row of the result as a hash */
function db_fetch_row_prepared($sql, $params = array(), $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_row_prepared(\'' . clean_up_lines($sql) . '\', $params = (\'' . implode('\', \'', $params) . '\'), $log = ' . $log . ', $db_conn = ' . ($db_conn ? 'true' : 'false') .')' . "\n");
    }

    return db_execute_prepared($sql, $params, $log, $db_conn, 'Row', false, 'db_fetch_row_return');
}

function db_fetch_row_return($query) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_row_return($query)' . "\n");
    }

#https://github.com/netniV/cisco-sfp/issues/10
print "\nDBG101_sql:" . $sql;

    if ($query->rowCount()) {
        $r = $query->fetchAll(PDO::FETCH_ASSOC);
    }

    return (isset($r[0])) ? $r[0] : array();
}

/* db_fetch_assoc - run a 'select' sql query and return all rows found
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - the entire result set as a multi-dimensional hash */
function db_fetch_assoc($sql, $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_assoc($sql, $log = true, $db_conn = false)' . "\n");
    }

    return db_fetch_assoc_prepared($sql, array(), $log, $db_conn);
}

/* db_fetch_assoc_prepared - run a 'select' sql query and return all rows found
   @param $sql - the sql query to execute
   @param $log - whether to log error messages, defaults to true
   @returns - the entire result set as a multi-dimensional hash */
function db_fetch_assoc_prepared($sql, $params = array(), $log = true, $db_conn = false) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_assoc_prepared($sql, $params = array(), $log = true, $db_conn = false)' . "\n");
    }

    return db_execute_prepared($sql, $params, $log, $db_conn, 'Row', array(), 'db_fetch_assoc_return');
}

function db_fetch_assoc_return($query) {
    global $config;

    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_fetch_assoc_return($query)' . "\n");
    }

    $r = $query->fetchAll(PDO::FETCH_ASSOC);
    return (is_array($r)) ? $r : array();
}

/* db_fetch_insert_id - get the last insert_id or auto incriment
   @returns - the id of the last auto increment row that was created */
function db_fetch_insert_id($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
    }

    if (is_object($db_conn)) {
        return $db_conn->lastInsertId();
    }

    return false;
}

/* db_affected_rows - return the number of rows affected by the last transaction
 * @returns - the number of rows affected by the last transaction */
function db_affected_rows($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    return $db_conn->affected_rows;
}

/* db_add_column - add a column to table
   @param $table - the name of the table
   @param $column - array of column data ex: array('name' => 'test' . rand(1, 200), 'type' => 'varchar (255)', 'NULL' => false)
   @param $log - whether to log error messages, defaults to true
   @returns - '1' for success, '0' for error */
function db_add_column($table, $column, $log = true, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
    if ($result === false) {
        return false;
    }

    $columns = array();
    foreach($result as $arr) {
        $columns[] = $arr['Field'];
    }

    if (isset($column['name']) && !in_array($column['name'], $columns)) {
        $sql = 'ALTER TABLE `' . $table . '` ADD `' . $column['name'] . '`';
        if (isset($column['type'])) {
            $sql .= ' ' . $column['type'];
        }

        if (isset($column['unsigned'])) {
            $sql .= ' unsigned';
        }

        if (isset($column['NULL']) && $column['NULL'] === false) {
            $sql .= ' NOT NULL';
        }

        if (isset($column['NULL']) && $column['NULL'] === true && !isset($column['default'])) {
            $sql .= ' default NULL';
        }

        if (isset($column['default'])) {
            if (strtolower($column['type']) == 'timestamp' && $column['default'] === 'CURRENT_TIMESTAMP') {
                $sql .= ' default CURRENT_TIMESTAMP';
            } else {
                $sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
            }
        }

        if (isset($column['on_update'])) {
            $sql .= ' ON UPDATE ' . $column['on_update'];
        }

        if (isset($column['auto_increment'])) {
            $sql .= ' auto_increment';
        }

        if (isset($column['comment'])) {
            $sql .= " COMMENT '" . $column['comment'] . "'";
        }

        if (isset($column['after'])) {
            $sql .= ' AFTER ' . $column['after'];
        }

        return db_execute($sql, $log, $db_conn);
    }

    return true;
}

/* db_remove_column - remove a column to table
   @param $table - the name of the table
   @param $column - column name
   @param $log - whether to log error messages, defaults to true
   @returns - '1' for success, '0' for error */
function db_remove_column($table, $column, $log = true, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
    $columns = array();
    foreach($result as $arr) {
        $columns[] = $arr['Field'];
    }

    if (isset($column) && in_array($column, $columns)) {
        $sql = 'ALTER TABLE `' . $table . '` DROP `' . $column . '`';
        return db_execute($sql, $log, $db_conn);
    }

    return true;
}

/* db_add_index - adds a new index to a table
   @param $table - the name of the table
   @param $type - the type of the index
   @param $key - the name of the index
   @param $columns - an array that defines the columns to include in the index
   @returns - (bool) the result of the operation true or false */
function db_add_index($table, $type, $key, $columns) {
    if (!is_array($columns)) {
        $columns = array($columns);
    }

    $sql = 'ALTER TABLE `' . $table . '` ADD ' . $type . ' `' . $key . '`(`' . implode('`,`', $columns) . '`)';

    if (db_index_exists($table, $key, false)) {
        $type = str_ireplace('UNIQUE ', '', $type);
        if (!db_execute("ALTER TABLE $table DROP $type $key")) {
            return false;
        }
    }

    return db_execute($sql);
}

/* db_index_exists - checks whether an index exists
   @param $table - the name of the table
   @param $index - the name of the index
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_index_exists($table, $index, $log = true, $db_conn = false) {
    global $database_log, $config;

    if (!isset($database_log)) {
        $database_log = false;
    }

    $_log  = $database_log;
    $database_log = false;

    $_data = db_fetch_assoc("SHOW KEYS FROM `$table`", $log, $db_conn);
    $_keys = array_rekey($_data, "Key_name", "Key_name");

    $database_log = $_log;
    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_index_exists(\'' . $table . '\', \'' . $index .'\'): '
            . in_array($index, $_keys) . ' - '
            . clean_up_lines(var_export($_keys, true)));
    }

    return in_array($index, $_keys);
}

/* db_index_exists - checks whether an index exists
   @param $table - the name of the table
   @param $index - the name of the index
   @param $columns - the columns of the index that should match
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_index_matches($table, $index, $columns, $log = true, $db_conn = false) {
    global $database_log, $config;

    if (!isset($database_log)) {
        $database_log = false;
    }

    if (!is_array($columns)) {
        $columns = array($columns);
    }

    $_log  = $database_log;
    $database_log = false;

    $_data = db_fetch_assoc("SHOW KEYS FROM `$table`", $log, $db_conn);
    $_cols = array();
    if ($_data !== false) {
        foreach ($_data as $key_col) {
            $key = $key_col['Key_name'];
            if ($key == $index) {
                $_cols[] = $key_col['Column_name'];
            }
        }
    }

    $status = 0;
    foreach ($columns as $column) {
        if (!in_array($column, $_cols)) {
            $status = -1;
            break;
        }
    }

    if ($status == 0) {
        foreach ($_cols as $column) {
            if (!in_array($column, $columns)) {
                $status = 1;
            }
        }
    }

    $database_log = $_log;
    if (!empty($config['DEBUG_SQL_FLOW'])) {
        db_echo_sql('db_index_matches(\'' . $table . '\', \'' . $index .'\'): '
            . $status . "\n ::: "
            . clean_up_lines(var_export($columns, true))
            . " ::: "
            . clean_up_lines(var_export($_cols, true)));
    }

    return $status;
}

/* db_table_exists - checks whether a table exists
   @param $table - the name of the table
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_table_exists($table, $log = true, $db_conn = false) {
    static $results;

    if (isset($results[$table]) && !defined('IN_CACTI_INSTALL') && !defined('IN_PLUGIN_INSTALL')) {
        return $results[$table];
    }

    // Separate the database from the table and remove backticks
    preg_match("/([`]{0,1}(?<database>[\w_]+)[`]{0,1}\.){0,1}[`]{0,1}(?<table>[\w_]+)[`]{0,1}/", $table, $matches);

    if ($matches !== false && array_key_exists('table', $matches)) {
        $sql = 'SHOW TABLES LIKE \'' . $matches['table'] . '\'';

        $results[$table] = (db_fetch_cell($sql, '', $log, $db_conn) ? true : false);

        return $results[$table];
    }

    return false;
}

/* db_cacti_initialized - checks whether cacti has been initialized properly and if not exits with a message
   @param $is_web - is the session a web session.
   @returns - (null)  */
function db_cacti_initialized($is_web = true) {
    global $database_sessions, $database_default, $config, $database_hostname, $database_port, $config;

    $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

    if (!is_object($db_conn)) {
        return false;
    }

    $query = $db_conn->prepare('SELECT cacti FROM version');
    $query->execute();
    $errorinfo = $query->errorInfo();
    $query->closeCursor();

    if ($errorinfo[1] != 0) {
        print ($is_web ? '<head><link href="' . $config['url_path'] . 'include/themes/modern/main.css" type="text/css" rel="stylesheet"></head>':'');
        print ($is_web ? '<table style="height:40px;"><tr><td></td></tr></table>':'');
        print ($is_web ? '<table style="margin-left:auto;margin-right:auto;width:80%;border:1px solid rgba(98,125,77,1)" class="cactiTable"><tr class="cactiTableTitle"><td style="color:snow;font-weight:bold;">Fatal Error - Cacti Database Not Initialized</td></tr>':'');
        print ($is_web ? '<tr class="installArea"><td>':'');
        print ($is_web ? '<p>':'') . 'The Cacti Database has not been initialized.  Please initilize it before continuing.' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p>':'') . 'To initilize the Cacti database, issue the following commands either as root or using a valid account.' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p style="font-weight:bold;padding-left:25px;">':'') . '  mysqladmin -uroot -p create cacti' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p style="font-weight:bold;padding-left:25px;">':'') . '  mysql -uroot -p -e "grant all on cacti.* to \'someuser\'@\'localhost\' identified by \'somepassword\'"' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p style="font-weight:bold;padding-left:25px;">':'') . '  mysql -uroot -p -e "grant select on mysql.time_zone_name to \'someuser\'@\'localhost\' identified by \'somepassword\'"' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p style="font-weight:bold;padding-left:25px;">':'') . '  mysql -uroot -p cacti < /pathcacti/cacti.sql' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p>':'') . 'Where <b>/pathcacti/</b> is the path to your Cacti install location.' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p>':'') . 'Change <b>someuser</b> and <b>somepassword</b> to match your site preferences.  The defaults are <b>cactiuser</b> for both user and password.' . ($is_web ? '</p>':"\n");
        print ($is_web ? '<p>':'') . '<b>NOTE:</b> When installing a remote poller, the <b>config.php</b> file must be writable by the Web Server account, and must include valid connection information to the main Cacti server.  The file should be changed to read only after the install is completed.' . ($is_web ? '</p>':"\n");
        print ($is_web ? '</td></tr></table>':'');
        exit;
    }
}

/* db_column_exists - checks whether a column exists
   @param $table - the name of the table
   @param $column - the name of the column
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_column_exists($table, $column, $log = true, $db_conn = false) {
    static $results = array();

    if (isset($results[$table][$column]) && !defined('IN_CACTI_INSTALL') && !defined('IN_PLUGIN_INSTALL')) {
        return $results[$table][$column];
    }

    $results[$table][$column] = (db_fetch_cell("SHOW columns FROM `$table` LIKE '$column'", '', $log, $db_conn) ? true : false);

    return $results[$table][$column];
}

/* db_get_table_column_types - returns all the types for each column of a table
   @param $table - the name of the table
   @returns - (array) an array of column types indexed by the column names */
function db_get_table_column_types($table, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $columns = db_fetch_assoc("SHOW COLUMNS FROM $table", false, $db_conn);
    $cols    = array();
    if (cacti_sizeof($columns)) {
        foreach($columns as $col) {
            $cols[$col['Field']] = array('type' => $col['Type'], 'null' => $col['Null'], 'default' => $col['Default'], 'extra' => $col['Extra']);;
        }
    }

    return $cols;
}

function db_update_table($table, $data, $removecolumns = false, $log = true, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    if (!db_table_exists($table, $log, $db_conn)) {
        return db_table_create($table, $data, $log, $db_conn);
    }

    $allcolumns = array();
    foreach ($data['columns'] as $column) {
        $allcolumns[] = $column['name'];
        if (!db_column_exists($table, $column['name'], $log, $db_conn)) {
            if (!db_add_column($table, $column, $log, $db_conn)) {
                return false;
            }
        } else {
            // Check that column is correct and fix it
            // FIXME: Need to still check default value
            $arr = db_fetch_row("SHOW columns FROM `$table` LIKE '" . $column['name'] . "'", $log, $db_conn);
            if ($column['type'] != $arr['Type'] || (isset($column['NULL']) && ($column['NULL'] ? 'YES' : 'NO') != $arr['Null'])
                || (isset($column['auto_increment']) && ($column['auto_increment'] ? 'auto_increment' : '') != $arr['Extra'])) {
                $sql = 'ALTER TABLE `' . $table . '` CHANGE `' . $column['name'] . '` `' . $column['name'] . '`';
                if (isset($column['type'])) {
                    $sql .= ' ' . $column['type'];
                }

                if (isset($column['unsigned'])) {
                    $sql .= ' unsigned';
                }

                if (isset($column['NULL']) && $column['NULL'] == false) {
                    $sql .= ' NOT NULL';
                }

                if (isset($column['NULL']) && $column['NULL'] == true && !isset($column['default'])) {
                    $sql .= ' default NULL';
                }

                if (isset($column['default'])) {
                    if (strtolower($column['type']) == 'timestamp' && $column['default'] === 'CURRENT_TIMESTAMP') {
                        $sql .= ' default CURRENT_TIMESTAMP';
                    } else {
                        $sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
                    }
                }

                if (isset($column['on_update'])) {
                    $sql .= ' ON UPDATE ' . $column['on_update'];
                }

                if (isset($column['auto_increment'])) {
                    $sql .= ' auto_increment';
                }

                if (isset($column['comment'])) {
                    $sql .= " COMMENT '" . $column['comment'] . "'";
                }

                if (!db_execute($sql, $log, $db_conn)) {
                    return false;
                }
            }
        }
    }

    if ($removecolumns) {
        $result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
        foreach($result as $arr) {
            if (!in_array($arr['Field'], $allcolumns)) {
                if (!db_remove_column($table, $arr['Field'], $log, $db_conn)) {
                    return false;
                }
            }
        }
    }

    $info = db_fetch_row("SELECT ENGINE, TABLE_COMMENT
        FROM information_schema.TABLES
        WHERE TABLE_SCHEMA = SCHEMA()
        AND TABLE_NAME = '$table'", $log, $db_conn);

    if (isset($info['TABLE_COMMENT']) && isset($data['comment']) && str_replace("'", '', $info['TABLE_COMMENT']) != str_replace("'", '', $data['comment'])) {
        if (!db_execute("ALTER TABLE `$table` COMMENT '" . str_replace("'", '', $data['comment']) . "'", $log, $db_conn)) {
            return false;
        }
    }

    if (isset($info['ENGINE']) && isset($data['type']) && strtolower($info['ENGINE']) != strtolower($data['type'])) {
        if (!db_execute("ALTER TABLE `$table` ENGINE = " . $data['type'], $log, $db_conn)) {
            return false;
        }
    }

    // Correct any indexes
    $indexes = db_fetch_assoc("SHOW INDEX FROM `$table`", $log, $db_conn);
    $allindexes = array();

    foreach ($indexes as $index) {
        $allindexes[$index['Key_name']][$index['Seq_in_index']-1] = $index['Column_name'];
    }

    foreach ($allindexes as $n => $index) {
        if ($n != 'PRIMARY' && isset($data['keys'])) {
            $removeindex = true;
            foreach ($data['keys'] as $k) {
                if ($k['name'] == $n) {
                    $removeindex = false;
                    $add = array_diff($k['columns'], $index);
                    $del = array_diff($index, $k['columns']);
                    if (!empty($add) || !empty($del)) {
                        if (!db_execute("ALTER TABLE `$table` DROP INDEX `$n`", $log, $db_conn) ||
                            !db_execute("ALTER TABLE `$table` ADD INDEX `$n` (" . $k['name'] . '` (' . db_format_index_create($k['columns']) . ')', $log, $db_conn)) {
                            return false;
                        }
                    }
                    break;
                }
            }

            if ($removeindex) {
                if (!db_execute("ALTER TABLE `$table` DROP INDEX `$n`", $log, $db_conn)) {
                    return false;
                }
            }
        }
    }

    // Add any indexes
    if (isset($data['keys'])) {
        foreach ($data['keys'] as $k) {
            if (!isset($allindexes[$k['name']])) {
                if (!db_execute("ALTER TABLE `$table` ADD INDEX `" . $k['name'] . '` (' . db_format_index_create($k['columns']) . ')', $log, $db_conn)) {
                    return false;
                }
            }
        }
    }

    // FIXME: It won't allow us to drop a primary key that is set to auto_increment

    // Check Primary Key
    if (!isset($data['primary']) && isset($allindexes['PRIMARY'])) {
        if (!db_execute("ALTER TABLE `$table` DROP PRIMARY KEY", $log, $db_conn)) {
            return false;
        }
        unset($allindexes['PRIMARY']);
    }

    if (isset($data['primary'])) {
        if (!isset($allindexes['PRIMARY'])) {
            // No current primary key, so add it
            if (!db_execute("ALTER TABLE `$table` ADD PRIMARY KEY(" . db_format_index_create($data['primary']) . ')', $log, $db_conn)) {
                return false;
            }
        } else {
            $add = array_diff($data['primary'], $allindexes['PRIMARY']);
            $del = array_diff($allindexes['PRIMARY'], $data['primary']);
            if (!empty($add) || !empty($del)) {
                if (!db_execute("ALTER TABLE `$table` DROP PRIMARY KEY", $log, $db_conn) ||
                    !db_execute("ALTER TABLE `$table` ADD PRIMARY KEY(" . db_format_index_create($data['primary']) . ')', $log, $db_conn)) {
                    return false;
                }
            }
        }
    }

    if (isset($data['row_format']) && db_get_global_variable('innodb_file_format', $db_conn) == 'Barracuda') {
        db_execute("ALTER TABLE `$table` ROW_FORMAT=" . $data['row_format'], $log, $db_conn);
    }

    $charset= '';
    if (isset($data['charset'])) {
        $charset = ' DEFAULT CHARSET=' . $data['charset'];
    }

    if ($charset != '') {
        db_execute("ALTER TABLE `$table` " . $charset, $log, $db_conn);
    }

    return true;
}

function db_format_index_create($indexes) {
    if (is_array($indexes)) {
        $outindex = '';
        foreach($indexes as $index) {
            $index = trim($index);
            if (substr($index, -1) == ')') {
                $outindex .= ($outindex != '' ? ',':'') . $index;
            } else {
                $outindex .= ($outindex != '' ? ',':'') . '`' . $index . '`';
            }
        }

        return $outindex;
    } else {
        $indexes = trim($indexes);
        if (substr($indexes, -1) == ')') {
            return $indexes;
        } else {
            return '`' . trim($indexes, ' `') . '`';
        }
    }
}

/* db_table_create - checks whether a table exists
   @param $table - the name of the table
   @param $data - data array
   @param $log - whether to log error messages, defaults to true
   @returns - (bool) the output of the sql query as a single variable */
function db_table_create($table, $data, $log = true, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    if (!db_table_exists($table, $log, $db_conn)) {
        $c = 0;
        $sql = 'CREATE TABLE `' . $table . "` (\n";
        foreach ($data['columns'] as $column) {
            if (isset($column['name'])) {
                if ($c > 0) {
                    $sql .= ",\n";
                }

                $sql .= '`' . $column['name'] . '`';

                if (isset($column['type'])) {
                    $sql .= ' ' . $column['type'];
                }

                if (isset($column['unsigned'])) {
                    $sql .= ' unsigned';
                }

                if (isset($column['NULL']) && $column['NULL'] == false) {
                    $sql .= ' NOT NULL';
                }

                if (isset($column['NULL']) && $column['NULL'] == true && !isset($column['default'])) {
                    $sql .= ' default NULL';
                }

                if (isset($column['default'])) {
                    if (strtolower($column['type']) == 'timestamp' && $column['default'] === 'CURRENT_TIMESTAMP') {
                        $sql .= ' default CURRENT_TIMESTAMP';
                    } else {
                        $sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
                    }
                }

                if (isset($column['on_update'])) {
                    $sql .= ' ON UPDATE ' . $column['on_update'];
                }

                if (isset($column['comment'])) {
                    $sql .= " COMMENT '" . $column['comment'] . "'";
                }

                if (isset($column['auto_increment'])) {
                    $sql .= ' auto_increment';
                }

                $c++;
            }
        }

        if (isset($data['primary'])) {
            if (is_array($data['primary'])) {
                $sql .= ",\n PRIMARY KEY (`" . implode('`,`'. $data['primary']) . '`)';
            } else {
                $sql .= ",\n PRIMARY KEY (`" . $data['primary'] . '`)';
            }
        }

        if (isset($data['keys']) && cacti_sizeof($data['keys'])) {
            foreach ($data['keys'] as $key) {
                if (isset($key['name'])) {
                    if (is_array($key['columns'])) {
                        $sql .= ",\n KEY `" . $key['name'] . '` (`' . implode('`,`', $key['columns']) . '`)';
                    } else {
                        $sql .= ",\n KEY `" . $key['name'] . '` (`' . $key['columns'] . '`)';
                    }
                }
            }
        }
        $sql .= ') ENGINE = ' . $data['type'];

        if (isset($data['comment'])) {
            $sql .= " COMMENT = '" . $data['comment'] . "'";
        }

        if (isset($data['charset'])) {
            $sql .= ' DEFAULT CHARSET=' . $data['charset'];
        }

        if (isset($data['row_format']) && db_get_global_variable('innodb_file_format', $db_conn) == 'Barracuda') {
            $sql .= ' ROW_FORMAT=' . $data['row_format'];
        }

        return db_execute($sql, $log, $db_conn);
    }
}

/* db_get_global_variable - get the value of a global variable
   @param $variable - the variable to obtain
   @param $db_conn - the database connection to use
   @returns - (string) the value of the variable if found */
function db_get_global_variable($variable, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $data = db_fetch_row("SHOW GLOBAL VARIABLES LIKE '$variable'", true, $db_conn);

    if (cacti_sizeof($data)) {
        return $data['Value'];
    } else {
        return false;
    }
}

/* db_get_session_variable - get the value of a session variable
   @param $variable - the variable to obtain
   @param $db_conn - the database connection to use
   @returns - (string) the value of the variable if found */
function db_get_session_variable($variable, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    $data = db_fetch_row("SHOW SESSION VARIABLES LIKE '$variable'", true, $db_conn);

    if (cacti_sizeof($data)) {
        return $data['Value'];
    } else {
        return false;
    }
}

/* db_begin_transaction - start a transaction
   @param $db_conn - the database connection to use
   @returns - (bool) if the begin transaction was successful */
function db_begin_transaction($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    return $db_conn->beginTransaction();
}

/* db_commit_transaction - commit a transaction
   @param $db_conn - the database connection to use
   @returns - (bool) if the commit transaction was successful */
function db_commit_transaction($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    return $db_conn->commit();
}

/* db_rollback_transaction - rollback a transaction
   @param $db_conn - the database connection to use
   @returns - (bool) if the rollback transaction was successful */
function db_rollback_transaction($db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    return $db_conn->rollBack();
}

/* array_to_sql_or - loops through a single dimentional array and converts each
     item to a string that can be used in the OR portion of an sql query in the
     following form:
        column=item1 OR column=item2 OR column=item2 ...
   @param $array - the array to convert
   @param $sql_column - the column to set each item in the array equal to
   @returns - a string that can be placed in a SQL OR statement */
function array_to_sql_or($array, $sql_column) {
    /* if the last item is null; pop it off */
    if (end($array) === null) {
        array_pop($array);
    }

    if (cacti_sizeof($array)) {
        $sql_or = "($sql_column IN('" . implode("','", $array) . "'))";

        return $sql_or;
    }
}

/* db_replace - replaces the data contained in a particular row
   @param $table_name - the name of the table to make the replacement in
   @param $array_items - an array containing each column -> value mapping in the row
   @param $keyCols - a string or array of primary keys
   @param $autoQuote - whether to use intelligent quoting or not
   @returns - the auto incriment id column (if applicable) */
function db_replace($table_name, $array_items, $keyCols, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
    }

    cacti_log("DEVEL: SQL Replace on table '$table_name': '" . serialize($array_items) . "'", false, 'DBCALL', POLLER_VERBOSITY_DEVDBG);

    _db_replace($db_conn, $table_name, $array_items, $keyCols);

    return db_fetch_insert_id($db_conn);
}

// FIXME:  Need to Rename and cleanup a bit

function _db_replace($db_conn, $table, $fieldArray, $keyCols) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];

        if (!is_object($db_conn)) {
            return false;
        }
    }

    if (!is_array($keyCols)) {
        $keyCols = array($keyCols);
    }

    $sql  = "INSERT INTO $table (";
    $sql2 = '';
    $sql3 = '';

    $first  = true;
    $first3 = true;
    foreach($fieldArray as $k => $v) {
        if (!$first) {
            $sql  .= ', ';
            $sql2 .= ', ';
        }
        $sql   .= "`$k`";
        $sql2  .= $v;
        $first  = false;

        if (in_array($k, $keyCols)) continue; // skip UPDATE if is key

        if (!$first3) {
            $sql3 .= ', ';
        }

        $sql3 .= "`$k`=VALUES(`$k`)";

        $first3 = false;
    }

    $sql .= ") VALUES ($sql2)" . ($sql3 != '' ? " ON DUPLICATE KEY UPDATE $sql3" : '');

    $return_code = db_execute($sql, true, $db_conn);

    if (!$return_code) {
        cacti_log("ERROR: SQL Save Failed for Table '$table'.  SQL:'" . clean_up_lines($sql) . "'", false, 'DBCALL');
    }

    return db_fetch_insert_id($db_conn);
}

/* sql_save - saves data to an sql table
   @param $array_items - an array containing each column -> value mapping in the row
   @param $table_name - the name of the table to make the replacement in
   @param $key_cols - the primary key(s)
   @returns - the auto incriment id column (if applicable) */
function sql_save($array_items, $table_name, $key_cols = 'id', $autoinc = true, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port, $database_last_error;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
    }

    $log = true;
    if (!db_table_exists($table_name, $log, $db_conn)) {
        $error_message = "SQL Save on table '$table_name': Table does not exist, unable to save!";
        raise_message('sql_save_table', $error_message, MESSAGE_LEVEL_ERROR);
        cacti_log('ERROR: ' . $error_message, false, 'DBCALL');
        cacti_debug_backtrace('SQL', false, true, 0, 1);
        return false;
    }

    $cols = db_get_table_column_types($table_name, $db_conn);

    cacti_log("DEVEL: SQL Save on table '$table_name': '" . serialize($array_items) . "'", false, 'DBCALL', POLLER_VERBOSITY_DEVDBG);

    foreach ($array_items as $key => $value) {
        if (!isset($cols[$key])) {
            $error_message = "SQL Save on table '$table_name': Column '$key' does not exist, unable to save!";
            raise_message('sql_save_key', $error_message, MESSAGE_LEVEL_ERROR);
            cacti_log('ERROR: ' . $error_message, false, 'DBCALL');
            cacti_debug_backtrace('SQL', false, true, 0, 1);
            return false;
        }

        if (strstr($cols[$key]['type'], 'int') !== false ||
            strstr($cols[$key]['type'], 'float') !== false ||
            strstr($cols[$key]['type'], 'double') !== false ||
            strstr($cols[$key]['type'], 'decimal') !== false) {
            if ($value == '') {
                if ($cols[$key]['null'] == 'YES') {
                    // TODO: We should make 'NULL', but there are issues that need to be addressed first
                    $array_items[$key] = 0;
                } elseif (strpos($cols[$key]['extra'], 'auto_increment') !== false) {
                    $array_items[$key] = 0;
                } elseif ($cols[$key]['default'] == '') {
                    // TODO: We should make 'NULL', but there are issues that need to be addressed first
                    $array_items[$key] = 0;
                } else {
                    $array_items[$key] = $cols[$key]['default'];
                }
            } elseif (empty($value)) {
                $array_items[$key] = 0;
            } else {
                $array_items[$key] = $value;
            }
        } else {
            $array_items[$key] = db_qstr($value);
        }
    }

    $replace_result = _db_replace($db_conn, $table_name, $array_items, $key_cols);

    /* get the last AUTO_ID and return it */
    if (!$replace_result || db_fetch_insert_id($db_conn) == '0') {
        if (!is_array($key_cols)) {
            if (isset($array_items[$key_cols])) {
                return str_replace('"', '', $array_items[$key_cols]);
            }
        }

        return false;
    } else {
        return $replace_result;
    }
}

function db_qstr($s, $db_conn = false) {
    global $database_sessions, $database_default, $database_hostname, $database_port;

    /* check for a connection being passed, if not use legacy behavior */
    if (!is_object($db_conn)) {
        $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
    }

    if (is_null($s)) {
        return 'NULL';
    }

    if (is_object($db_conn)) {
        return $db_conn->quote($s);
    }

    $s = str_replace(array('\\', "\0", "'"), array('\\\\', "\\\0", "\\'"), $s);

    return  "'" . $s . "'";
}

function db_strip_control_chars($sql) {
    return trim(clean_up_lines($sql), ';');
}

function db_get_column_attributes($table, $columns) {
    if (empty($columns) || empty($table)) {
        return false;
    }

    if (!is_array($columns)) {
        $columns = explode(',', $columns);
    }

    $sql = 'SELECT * FROM information_schema.columns
        WHERE table_schema = SCHEMA()
        AND table_name = ?
        AND column_name IN (';

    $column_names = array();
    foreach ($columns as $column) {
        if (!empty($column)) {
            $sql .= (cacti_sizeof($column_names) ? ',' : '') . '?';
            $column_names[] = $column;
        }
    }
    $sql .= ')';

    $params = array_merge(array($table), $column_names);

    return db_fetch_assoc_prepared($sql, $params);
}

function db_get_columns_length($table, $columns) {
    $column_data = db_get_column_attributes($table, $columns);

    if (!empty($column_data)) {
        return array_rekey($column_data, 'COLUMN_NAME','CHARACTER_MAXIMUM_LENGTH');
    }

    return false;
}

function db_get_column_length($table, $column) {
    $column_data = db_get_columns_length($table, $column);

    if (!empty($column_data) && isset($column_data[$column])) {
        return $column_data[$column];
    }

    return false;
}

function db_check_password_length() {
    $len = db_get_column_length('user_auth', 'password');

    if ($len === false) {
        die(__('Failed to determine password field length, can not continue as may corrupt password'));
    } else if ($len < 80) {
        /* Ensure that the password length is increased before we start updating it */
        db_execute("ALTER TABLE user_auth MODIFY COLUMN password varchar(256) NOT NULL default ''");
        $len = db_get_column_length('user_auth','password');
        if ($len < 80) {
            die(__('Failed to alter password field length, can not continue as may corrupt password'));
        }
    }
}

function db_echo_sql($line, $force = false) {
    global $config;

    file_put_contents(sys_get_temp_dir() . '/cacti-sql.log', get_debug_prefix() . $line, FILE_APPEND);
}

/* db_error - return the last error from the database
   @returns - string - the last database error if any */
function db_error() {
    global $database_last_error;

    return $database_last_error;
}

/* db_get_default_database - Get the database name of the current database or return the default database name
   @returns - string - either current db name or configuration default if no connection/name */
function db_get_default_database($db_conn = false) {
    global $database_default;

    $database = db_fetch_cell('SELECT DATABASE()', '', true, $db_conn);
    if (empty($database)) {
        $database = $database_default;
    }
}

/* db_force_remote_cnn - force the remote collector to use main data collector connection
   @returns - null */
function db_force_remote_cnn() {
    global $database_default, $database_hostname, $database_username, $database_password;
    global $database_port, $database_ssl, $database_ssl_key, $database_ssl_cert, $database_ssl_ca;

    global $rdatabase_default, $rdatabase_hostname, $rdatabase_username, $rdatabase_password;
    global $rdatabase_port, $rdatabase_ssl, $rdatabase_ssl_key, $rdatabase_ssl_cert, $rdatabase_ssl_ca;

    // Connection worked, so now override the default settings so that it will always utilize the remote connection
    $database_default   = $rdatabase_default;
    $database_hostname  = $rdatabase_hostname;
    $database_username  = $rdatabase_username;
    $database_password  = $rdatabase_password;
    $database_port      = $rdatabase_port;
    $database_ssl       = $rdatabase_ssl;
    $database_ssl_key   = $rdatabase_ssl_key;
    $database_ssl_cert  = $rdatabase_ssl_cert;
    $database_ssl_ca    = $rdatabase_ssl_ca;
}
pyron83 commented 1 year ago

@Luth1ng I gave a better a look at the script 'database.php'

it looks like i've this function at line 379 instead of 457:

 379 function db_fetch_cell($sql, $col_name = '', $log = true, $db_conn = false) {
 380         global $config;
 381 
 382         if (!empty($config['DEBUG_SQL_FLOW'])) {
 383                 db_echo_sql('db_fetch_cell($sql, $col_name = \'' . $col_name . '\', $log = true, $db_conn = false)' . "\n");
 384         }
pyron83 commented 1 year ago

@Luth1ng let me know if i should place the line you mentioned at line 379 instead of 457, or we should investigate the whole script (that is the original of Cacti 1.2.16-debian, I never modified or replaced it)

netniV commented 1 year ago

@pyron83 if you follow my suggestion for enabling DEBUG_SQL_FLOW via your script server script, this will log all database calls made during just the run of your script which would be best, instead of manually adding the code @Luth1ng suggested which would break cacti for other users.

netniV commented 1 year ago

Before line 31 in the script that was posted above (assuming you are using that), set the config value. It should look something like:

include_once("/usr/share/cacti/include/config.php");
include_once("/usr/share/cacti/include/global.php");
include_once("/usr/share/cacti/lib/snmp.php");

$config['DEBUG_SQL_FLOW'] = true;

if (!isset($called_by_script_server)) {
        array_shift($_SERVER["argv"]);
        print call_user_func_array("ss_sfp", $_SERVER["argv"]);
}

Note: The output log file may get quite large depending on what you are querying.

Luth1ng commented 1 year ago

@pyron83 yes you could add the line inside the db_fetch_cell function, but @netniV's debug option is better I guess

As you can easily backup your server, you should seriously consider updating your Cacti to the last available version. Your issue may be already solved...

pyron83 commented 1 year ago

@pyron83 yes you could add the line inside the db_fetch_cell function, but @netniV's debug option is better I guess

As you can easily backup your server, you should seriously consider updating your Cacti to the last available version. Your issue may be already solved...

I understand, but as mentioned above, the upgrade is contained in Debian Testing, while I'm in the stable branch. Before picking up a pkg from Testing, I would really appreciate to understand if this is bug of this version of Cacti, that is the latest on Debian 11.

This is why I believe @paulgevers was mentioned before.

pyron83 commented 1 year ago
include_once("/usr/share/cacti/include/config.php");
include_once("/usr/share/cacti/include/global.php");
include_once("/usr/share/cacti/lib/snmp.php");

$config['DEBUG_SQL_FLOW'] = true;

if (!isset($called_by_script_server)) {
        array_shift($_SERVER["argv"]);
        print call_user_func_array("ss_sfp", $_SERVER["argv"]);
}

If I undestand, you suggest to put those lines in script_server.php instead of modifying lib/database.php? Am I correct?

pyron83 commented 1 year ago

I followed @netniV suggestion and I put those lines in script_server.php (I hope I read correctly).

This is the result of the command mentioned by @Luth1ng ( "/usr/bin/php" -q /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php 'myswitch:169:2:161:500:1:10:mycommunity::::::' 'query' 'descr' > php-cacti-dbg; cat php-cacti-dbg )


# cat php-cacti-dbg

---Debug enabled for query descr command---

----------

DBG1_sensor_name:GigabitEthernet1/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1090
1090:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1096
1096:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1102
1102:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/7 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1108
1108:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/8 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1114
1114:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/9 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1120
1120:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/10 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1126
1126:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/11 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1132
1132:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1138
1138:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/24 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1145
1145:

----------

----------

DBG1_sensor_name:TenGigabitEthernet1/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1153
1153:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2090
2090:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2096
2096:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2102
2102:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/13 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2108
2108:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/14 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2114
2114:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2120
2120:

----------

----------

DBG1_sensor_name:TenGigabitEthernet2/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2127
2127:

----------
pyron83 commented 1 year ago

I can see that all DBGx_$objects are empty, but I don't know Cacti "inside" well enough to say if it's something meaningful, so I'm up to your suggestions.

I just wanna be sure that is a Cacti 1.2.16 bug before proceeding in any upgrade from Testing.

Thanks

netniV commented 1 year ago

That didn't seems to show the SQL statements. Did you put the commands in the script file you are running or script_server.php (which would be the wrong place)?

Also, add an extra line before setting the config value just to be sure ...

global $config;

It may be possible that from script_server the config variable is out of scope.

pyron83 commented 1 year ago

That didn't seems to show the SQL statements. Did you put the commands in the script file you are running or script_server.php (which would be the wrong place)?

Also, add an extra line before setting the config value just to be sure ...

global $config;

It may be possible that from script_server the config variable is out of scope.

ok I corrected the mistake and put those lines in /usr/share/cacti/site/scripts/ss_cisco_catalyst_sfp_querydescrdbg.php (the script @Luth1ng mentioned) but the result is the same

(OFC I reverted script_server.php to the original backup)



---Debug enabled for query descr command---

----------

DBG1_sensor_name:GigabitEthernet1/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1090
1090:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1096
1096:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1102
1102:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/7 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1108
1108:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/8 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1114
1114:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/9 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1120
1120:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/10 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1126
1126:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/11 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1132
1132:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1138
1138:

----------

----------

DBG1_sensor_name:GigabitEthernet1/0/24 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1145
1145:

----------

----------

DBG1_sensor_name:TenGigabitEthernet1/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 1153
1153:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/1 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2090
2090:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/2 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2096
2096:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2102
2102:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/13 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2108
2108:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/14 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2114
2114:

----------

----------

DBG1_sensor_name:GigabitEthernet2/0/15 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2120
2120:

----------

----------

DBG1_sensor_name:TenGigabitEthernet2/1/3 Transmit Power Sensor
DBG2_elsematched: true
DBG3_index:1
DBG4_host_id:
DBG5_snmp_index:
DBG6_alias:
DBG7_alias:

Function result for index 2127
2127:

----------