File: How-To-Data-Queries.md

package info (click to toggle)
cacti 1.2.24%2Bds1-1%2Bdeb12u5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 71,012 kB
  • sloc: php: 119,968; javascript: 29,780; sql: 2,632; xml: 1,823; sh: 1,248; perl: 194; makefile: 65; ruby: 9
file content (213 lines) | stat: -rw-r--r-- 6,865 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# How To Work with Data Queries

During the past few weeks as I've made various SNMP Data Query templates I've
ran into a few 'tricks' (which existing user scripts use) to make them work
with most devices. It'd probably be beneficial to publish these in some manner
on the documentation site so others don't have to stumble.

As you already know getting an index is the hardest thing users struggle with.
I've ran across three scenarios and their solutions:

## SNMP index is present

Basically mimic the interface.xml template which comes with Cacti
`(cacti/resource/snmp_queries/interface.xml)`.

SNMPWALK:

```console
Raw OIDs:
.1.3.6.1.2.1.2.2.1.1.1 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.1.2 = INTEGER: 2
.1.3.6.1.2.1.2.1.0 = INTEGER: 2
```

```console
Textual MIB names:
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifNumber.0 = INTEGER: 2
```

In the SNMP XML file, specify the `<oid_index>` and optional
`<oid_num_indexes>` fields. For example:

```XML
<interface>
    <name>Get SNMP Interfaces</name>
    <description>Queries a host for a list of monitorable interfaces</description>
    <oid_index>.1.3.6.1.2.1.2.2.1.1</oid_index>
    <oid_num_indexes>.1.3.6.1.2.1.2.1.0</oid_num_indexes>

    <fields>
        <ifIndex>
            <name>Index</name>
            <method>walk</method>
            <source>value</source>
            <direction>input</direction>
            <oid>.1.3.6.1.2.1.2.2.1.1</oid>
        </ifIndex>
    </fields>
</interface>
```

A verbose query from inside Cacti shows the following:

```shell
+ Running data query [1].
+ Found type = '3' [snmp query].
+ Found data query XML file at 'C:/Inetpub/wwwroot/cacti/resource/snmp_queries/interface.xml'
+ XML file parsed ok.
+ Executing SNMP walk for list of indexes @ '.1.3.6.1.2.1.2.2.1.1'
+ Index found at OID: 'iso.3.6.1.2.1.2.2.1.1.1' value: '1'
+ Index found at OID: 'iso.3.6.1.2.1.2.2.1.1.2' value: '2'
+ Located input field 'ifIndex' [walk]
+ Executing SNMP walk for data @ '.1.3.6.1.2.1.2.2.1.1'
+ Found item [ifIndex='1'] index: 1 [from value]
+ Found item [ifIndex='2'] index: 2 [from value]
```

## SNMP Index is a STRING

Some devices (like on a F5 BigIP) use a STRING to represent the Index due to
the fact it is user configurable. In this case we need Cacti to parse out the
variable length Index.

Sample of a STRING Index:

Raw OID:

```console
.1.3.6.1.4.1.3375.2.2.10.2.3.1.1.5.76.88.87.69.66 = STRING: "LXWEB"
.1.3.6.1.4.1.3375.2.2.10.2.3.1.1.6.69.80.88.87.69.66 = STRING: "EPXWEB"
```

Textual MIB names:

```console
F5-BIGIP-LOCAL-MIB::ltmVirtualServStatName."LXWEB" = STRING: LXWEB
F5-BIGIP-LOCAL-MIB::ltmVirtualServStatName."EPXWEB" = STRING: EPXWEB
```

Next we need to define a OID/REGEXP that will look for the start of the STRING
and create the Index.  In this case the regexp "^.{32}" matches the first 32
characters beginning at the start of the OID -- this is the length of the OID
from the leading dot up to the start of the index. Then the capturing parens
"(.*)" grab the remainder of the OID as a backreference. Use the following SNMP
XML script:

```XML
<interface>
    <name>Get F5 Big-IP Load Balancer Virtual Server Statistics</name>
    <oid_index>.1.3.6.1.4.1.3375.2.2.10.2.3.1.1</oid_index>
        <oid_index_parse>OID/REGEXP:^.{32}(.*)</oid_index_parse>
        <index_order>vsIndex</index_order>
        <index_order_type>alphabetic</index_order_type>

        <fields>
        <vsIndex>
            <name>Index</name>
            <source>index</source>
            <direction>input</direction>
        </vsIndex>
    </fields>
</interface>
```

After creating the Data Query Data & Graph templates in Cacti a verbose query
will spit out the following:

```shell
+ Running data query [20].
+ Found type = '3' [snmp query].
+ Found data query XML file at 'C:/Inetpub/wwwroot/cacti/resource/snmp_queries/f5_bigip_vs.xml'
+ XML file parsed ok.
+ Executing SNMP walk for list of indexes @ '.1.3.6.1.4.1.3375.2.2.10.2.3.1.1'
+ Index found at OID: 'enterprises.3375.2.2.10.2.3.1.1.5.76.88.87.69.66' value: 'LXWEB'
+ Index found at OID: 'enterprises.3375.2.2.10.2.3.1.1.6.69.80.88.87.69.66' value: 'EPXWEB'
+ index_parse at OID: 'enterprises.3375.2.2.10.2.3.1.1.5.76.88.87.69.66' results: '5.76.88.87.69.66'
+ index_parse at OID: 'enterprises.3375.2.2.10.2.3.1.1.6.69.80.88.87.69.66' results: '6.69.80.88.87.69.66'
+ Inserting index data for field 'vsIndex' [value='5.76.88.87.69.66']
+ Inserting index data for field 'vsIndex' [value='6.69.80.88.87.69.66']
```

## SNMP Index does not exist

Some devices do not offer a traditional Index OID to query. Here we need to
create/fake the index for Cacti. This is accomplished once again with a simple
REGEX to split off the last OID (or middle, etc) to create the index for cacti.

SNMPWALK:

Raw OIDs:

```console
.1.3.6.1.2.1.7.1.0 = Counter32: 69367
.1.3.6.1.2.1.7.2.0 = Counter32: 11
.1.3.6.1.2.1.7.3.0 = Counter32: 0
.1.3.6.1.2.1.7.4.0 = Counter32: 64392
```

Textual MIB name:

```console
UDP-MIB::udpInDatagrams.0 = Counter32: 69458
UDP-MIB::udpNoPorts.0 = Counter32: 11
UDP-MIB::udpInErrors.0 = Counter32: 0
UDP-MIB::udpOutDatagrams.0 = Counter32: 64471
```

Consulting the MIB file for these OIDs, we know that the associated index will
always be "0" for each OID.  We'll want to split this off with the
REGEX.

Create the following SNMP XML file:

```XML
<interface>
    <name>Get RFC1213 Stats</name>
    <description>Management Information Base for Network Management of TCP/IP-based internets</description>
    <oid_index>.1.3.6.1.2.1.7.2</oid_index>
    <oid_index_parse>OID/REGEXP:.*\.([0-9]{1,2})$</oid_index_parse>
    <index_order>Index</index_order>
    <index_order_type>alphabetic</index_order_type>

    <fields>
        <Index>
            <name>Index</name>
            <source>index</source>
            <direction>input</direction>
        </Index>
    </fields>
</interface>
```

Once all of the required templates have been created, a verbose query from
Cacti results in the following:

```shell
+ Running data query [23].
+ Found type = '3' [snmp query].
+ Found data query XML file at 'C:/Inetpub/wwwroot/cacti/resource/snmp_queries/RFC1213.xml'
+ XML file parsed ok.
+ Executing SNMP walk for list of indexes @ '.1.3.6.1.2.1.7.2'
+ Index found at OID: 'iso.3.6.1.2.1.7.2.0' value: '11'
+ index_parse at OID: 'iso.3.6.1.2.1.7.2.0' results: '0'
+ Inserting index data for field 'Index' [value='0']
```

## A note on Textual SNMP MIBS and SPINE

Please be aware the SPINE does not parse out textual Mibs.  This means that if
you were to use an OID that contained a string reference rather than numerical
this will cause Graphs to fail as they will not be generated due to spine not
reciving a value at each poll

Example of a bad OID reference for spine:

```shell
interfaces.mib.1.1.1.1.1
```

---
<copy>Copyright (c) 2004-2023 The Cacti Group</copy>