From e4b513e764eb0fd1347ab14e193b9a14ced21eec Mon Sep 17 00:00:00 2001
From: Daniel Nelson <daniel.nelson@influxdb.com>
Date: Mon, 30 Dec 2019 11:33:32 -0800
Subject: [PATCH] Rewrite documentation for snmp input (#6802)

---
 plugins/inputs/snmp/CONFIG-EXAMPLES.md |  65 ------
 plugins/inputs/snmp/DEBUGGING.md       |  53 -----
 plugins/inputs/snmp/README.md          | 307 ++++++++++++++-----------
 plugins/inputs/snmp/snmp.go            | 128 +++++------
 plugins/inputs/snmp/snmp_test.go       |  40 +---
 plugins/inputs/snmp_trap/README.md     |  62 +++--
 6 files changed, 276 insertions(+), 379 deletions(-)
 delete mode 100644 plugins/inputs/snmp/CONFIG-EXAMPLES.md
 delete mode 100644 plugins/inputs/snmp/DEBUGGING.md

diff --git a/plugins/inputs/snmp/CONFIG-EXAMPLES.md b/plugins/inputs/snmp/CONFIG-EXAMPLES.md
deleted file mode 100644
index a0a52eeb327ef..0000000000000
--- a/plugins/inputs/snmp/CONFIG-EXAMPLES.md
+++ /dev/null
@@ -1,65 +0,0 @@
-Here are a few configuration examples for different use cases.
-
-### Switch/router interface metrics
-
-This setup will collect data on all interfaces from three different tables, `IF-MIB::ifTable`, `IF-MIB::ifXTable` and `EtherLike-MIB::dot3StatsTable`. It will also add the name from `IF-MIB::ifDescr` and use that as a tag. Depending on your needs and preferences you can easily use `IF-MIB::ifName` or `IF-MIB::ifAlias` instead or in addition. The values of these are typically:
-
-    IF-MIB::ifName = Gi0/0/0
-    IF-MIB::ifDescr = GigabitEthernet0/0/0
-    IF-MIB::ifAlias = ### LAN ###
-
-This configuration also collects the hostname from the device (`RFC1213-MIB::sysName.0`) and adds as a tag. So each metric will both have the configured host/IP as `agent_host` as well as the device self-reported hostname as `hostname` and the name of the host that has collected these metrics as `host`.
-
-Here is the configuration that you add to your `telegraf.conf`:
-
-```
-[[inputs.snmp]]
-  agents = [ "host.example.com" ]
-  version = 2
-  community = "public"
-
-  [[inputs.snmp.field]]
-    name = "hostname"
-    oid = "RFC1213-MIB::sysName.0"
-    is_tag = true
-
-  [[inputs.snmp.field]]
-    name = "uptime"
-    oid = "DISMAN-EXPRESSION-MIB::sysUpTimeInstance"
-
-  # IF-MIB::ifTable contains counters on input and output traffic as well as errors and discards.
-  [[inputs.snmp.table]]
-    name = "interface"
-    inherit_tags = [ "hostname" ]
-    oid = "IF-MIB::ifTable"
-
-    # Interface tag - used to identify interface in metrics database
-    [[inputs.snmp.table.field]]
-      name = "ifDescr"
-      oid = "IF-MIB::ifDescr"
-      is_tag = true
-
-  # IF-MIB::ifXTable contains newer High Capacity (HC) counters that do not overflow as fast for a few of the ifTable counters
-  [[inputs.snmp.table]]
-    name = "interface"
-    inherit_tags = [ "hostname" ]
-    oid = "IF-MIB::ifXTable"
-
-    # Interface tag - used to identify interface in metrics database
-    [[inputs.snmp.table.field]]
-      name = "ifDescr"
-      oid = "IF-MIB::ifDescr"
-      is_tag = true
-
-  # EtherLike-MIB::dot3StatsTable contains detailed ethernet-level information about what kind of errors have been logged on an interface (such as FCS error, frame too long, etc)
-  [[inputs.snmp.table]]
-    name = "interface"
-    inherit_tags = [ "hostname" ]
-    oid = "EtherLike-MIB::dot3StatsTable"
-
-    # Interface tag - used to identify interface in metrics database
-    [[inputs.snmp.table.field]]
-      name = "ifDescr"
-      oid = "IF-MIB::ifDescr"
-      is_tag = true
-```
diff --git a/plugins/inputs/snmp/DEBUGGING.md b/plugins/inputs/snmp/DEBUGGING.md
deleted file mode 100644
index f357c58b51c52..0000000000000
--- a/plugins/inputs/snmp/DEBUGGING.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Debugging & Testing SNMP Issues
-
-### Install net-snmp on your system:
-
-Mac:
-
-```
-brew install net-snmp
-```
-
-### Run an SNMP simulator docker image to get a full MIB on port 161:
-
-```
-docker run -d -p 161:161/udp xeemetric/snmp-simulator
-```
-
-### snmpget:
-
-snmpget corresponds to the inputs.snmp.field configuration.
-
-```bash
-$ # get an snmp field with fully-qualified MIB name.
-$ snmpget -v2c -c public localhost:161 system.sysUpTime.0
-DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1643) 0:00:16.43
-
-$ # get an snmp field, outputting the numeric OID.
-$ snmpget -On -v2c -c public localhost:161 system.sysUpTime.0
-.1.3.6.1.2.1.1.3.0 = Timeticks: (1638) 0:00:16.38
-```
-
-### snmptranslate:
-
-snmptranslate can be used to translate an OID to a MIB name:
-
-```bash
-$ snmptranslate .1.3.6.1.2.1.1.3.0
-DISMAN-EVENT-MIB::sysUpTimeInstance
-```
-
-And to convert a partial MIB name to a fully qualified one:
-
-```bash
-$ snmptranslate -IR sysUpTime.0
-DISMAN-EVENT-MIB::sysUpTimeInstance
-```
-
-And to convert a MIB name to an OID:
-
-```bash
-$ snmptranslate -On -IR system.sysUpTime.0
-.1.3.6.1.2.1.1.3.0
-```
-
diff --git a/plugins/inputs/snmp/README.md b/plugins/inputs/snmp/README.md
index a15e5ddb6a5e1..68760968a2a42 100644
--- a/plugins/inputs/snmp/README.md
+++ b/plugins/inputs/snmp/README.md
@@ -1,180 +1,221 @@
-# SNMP Plugin
+# SNMP Input Plugin
 
-The SNMP input plugin gathers metrics from SNMP agents.
+The `snmp` input plugin uses polling to gather metrics from SNMP agents.
+Support for gathering individual OIDs as well as complete SNMP tables is
+included.
 
-## Configuration:
+### Prerequisites
 
-See additional SNMP plugin configuration examples [here](./CONFIG-EXAMPLES.md).
+This plugin uses the `snmptable` and `snmptranslate` programs from the
+[net-snmp][] project.  These tools will need to be installed into the `PATH` in
+order to be located.  Other utilities from the net-snmp project may be useful
+for troubleshooting, but are not directly used by the plugin.
 
-### Example:
+These programs will load available MIBs on the system.  Typically the default
+directory for MIBs is `/usr/share/snmp/mibs`, but if your MIBs are in a
+different location you may need to make the paths known to net-snmp.  The
+location of these files can be configured in the `snmp.conf` or via the
+`MIBDIRS` environment variable. See [`man 1 snmpcmd`][man snmpcmd] for more
+information.
 
-SNMP data:
-```
-.1.0.0.0.1.1.0 octet_str "foo"
-.1.0.0.0.1.1.1 octet_str "bar"
-.1.0.0.0.1.102 octet_str "bad"
-.1.0.0.0.1.2.0 integer 1
-.1.0.0.0.1.2.1 integer 2
-.1.0.0.0.1.3.0 octet_str "0.123"
-.1.0.0.0.1.3.1 octet_str "0.456"
-.1.0.0.0.1.3.2 octet_str "9.999"
-.1.0.0.1.1 octet_str "baz"
-.1.0.0.1.2 uinteger 54321
-.1.0.0.1.3 uinteger 234
-```
-
-Telegraf config:
+### Configuration
 ```toml
 [[inputs.snmp]]
-  agents = [ "127.0.0.1:161" ]
-  version = 2
-  community = "public"
-
-  name = "system"
-  [[inputs.snmp.field]]
-    name = "hostname"
-    oid = ".1.0.0.1.1"
-    is_tag = true
+  ## Agent addresses to retrieve values from.
+  ##   example: agents = ["udp://127.0.0.1:161"]
+  ##            agents = ["tcp://127.0.0.1:161"]
+  agents = ["udp://127.0.0.1:161"]
+
+  ## Timeout for each request.
+  # timeout = "5s"
+
+  ## SNMP version; can be 1, 2, or 3.
+  # version = 2
+
+  ## SNMP community string.
+  # community = "public"
+
+  ## Number of retries to attempt.
+  # retries = 3
+
+  ## The GETBULK max-repetitions parameter.
+  # max_repetitions = 10
+
+  ## SNMPv3 authentication and encryption options.
+  ##
+  ## Security Name.
+  # sec_name = "myuser"
+  ## Authentication protocol; one of "MD5", "SHA", or "".
+  # auth_protocol = "MD5"
+  ## Authentication password.
+  # auth_password = "pass"
+  ## Security Level; one of "noAuthNoPriv", "authNoPriv", or "authPriv".
+  # sec_level = "authNoPriv"
+  ## Context Name.
+  # context_name = ""
+  ## Privacy protocol used for encrypted messages; one of "DES", "AES" or "".
+  # priv_protocol = ""
+  ## Privacy password used for encrypted messages.
+  # priv_password = ""
+
+  ## Add fields and tables defining the variables you wish to collect.  This
+  ## example collects the system uptime and interface variables.  Reference the
+  ## full plugin documentation for configuration details.
   [[inputs.snmp.field]]
+    oid = "RFC1213-MIB::sysUpTime.0"
     name = "uptime"
-    oid = ".1.0.0.1.2"
+
   [[inputs.snmp.field]]
-    name = "loadavg"
-    oid = ".1.0.0.1.3"
-    conversion = "float(2)"
+    oid = "RFC1213-MIB::sysName.0"
+    name = "source"
+    is_tag = true
 
   [[inputs.snmp.table]]
-    name = "remote_servers"
-    inherit_tags = [ "hostname" ]
+    oid = "IF-MIB::ifTable"
+    name = "interface"
+    inherit_tags = ["source"]
+
     [[inputs.snmp.table.field]]
-      name = "server"
-      oid = ".1.0.0.0.1.1"
+      oid = "IF-MIB::ifDescr"
+      name = "ifDescr"
       is_tag = true
-    [[inputs.snmp.table.field]]
-      name = "connections"
-      oid = ".1.0.0.0.1.2"
-    [[inputs.snmp.table.field]]
-      name = "latency"
-      oid = ".1.0.0.0.1.3"
-      conversion = "float"
 ```
 
-Resulting output:
-```
-* Plugin: snmp, Collection 1
-> system,agent_host=127.0.0.1,host=mylocalhost,hostname=baz loadavg=2.34,uptime=54321i 1468953135000000000
-> remote_servers,agent_host=127.0.0.1,host=mylocalhost,hostname=baz,server=foo connections=1i,latency=0.123 1468953135000000000
-> remote_servers,agent_host=127.0.0.1,host=mylocalhost,hostname=baz,server=bar connections=2i,latency=0.456 1468953135000000000
-```
+#### Configure SNMP Requests
 
-#### Configuration via MIB:
+This plugin provides two methods for configuring the SNMP requests: `fields`
+and `tables`.  Use the `field` option to gather single ad-hoc variables.
+To collect SNMP tables, use the `table` option.
 
-This example uses the SNMP data above, but is configured via the MIB.
-The example MIB file can be found in the `testdata` directory. See the [MIB lookups](#mib-lookups) section for more information.
+##### Field
+
+Use a `field` to collect a variable by OID.  Requests specified with this
+option operate similar to the `snmpget` utility.
 
-Telegraf config:
 ```toml
 [[inputs.snmp]]
-  agents = [ "127.0.0.1:161" ]
-  version = 2
-  community = "public"
+  # ... snip ...
 
   [[inputs.snmp.field]]
-    oid = "TEST::hostname"
-    is_tag = true
-
-  [[inputs.snmp.table]]
-    oid = "TEST::testTable"
-    inherit_tags = [ "hostname" ]
-```
-
-Resulting output:
-```
-* Plugin: snmp, Collection 1
-> testTable,agent_host=127.0.0.1,host=mylocalhost,hostname=baz,server=foo connections=1i,latency="0.123" 1468953135000000000
-> testTable,agent_host=127.0.0.1,host=mylocalhost,hostname=baz,server=bar connections=2i,latency="0.456" 1468953135000000000
+    ## Object identifier of the variable as a numeric or textual OID.
+    oid = "RFC1213-MIB::sysName.0"
+
+    ## Name of the field or tag to create.  If not specified, it defaults to
+    ## the value of 'oid'. If 'oid' is numeric, an attempt to translate the
+    ## numeric OID into a textual OID will be made.
+    # name = ""
+
+    ## If true the variable will be added as a tag, otherwise a field will be
+    ## created.
+    # is_tag = false
+
+    ## Apply one of the following conversions to the variable value:
+    ##   float(X) Convert the input value into a float and divides by the
+    ##            Xth power of 10. Efficively just moves the decimal left
+    ##            X places. For example a value of `123` with `float(2)`
+    ##            will result in `1.23`.
+    ##   float:   Convert the value into a float with no adjustment. Same
+    ##            as `float(0)`.
+    ##   int:     Convert the value into an integer.
+    ##   hwaddr:  Convert the value to a MAC address.
+    ##   ipaddr:  Convert the value to an IP address.
+    # conversion = ""
 ```
 
-### Config parameters
+##### Table
 
-* `agents`: Default: `[]`
-List of SNMP agents to connect to in the form of `[tcp://]IP[:PORT]`. If `:PORT` is unspecified, it defaults to `161`. When using the optional prefix `tcp://`, SNMP over TCP will be used. Otherwise UDP is used as the transport protocol.
+Use a `table` to configure the collection of a SNMP table.  SNMP requests
+formed with this option operate similarly way to the `snmptable` command.
 
-* `version`: Default: `2`
-SNMP protocol version to use.
+Control the handling of specific table columns using a nested `field`.  These
+nested fields are specified similarly to a top-level `field`.
 
-* `community`: Default: `"public"`
-SNMP community to use.
+All columns of the SNMP table will be collected, it is not required to add a
+nested field for each column, only those which you wish to modify.  To exclude
+columns use [metric filtering][].
 
-* `max_repetitions`: Default: `50`
-Maximum number of iterations for repeating variables.
+One [metric][] is created for each row of the SNMP table.
 
-* `sec_name`:
-Security name for authenticated SNMPv3 requests.
-
-* `auth_protocol`: Values: `"MD5"`,`"SHA"`,`""`. Default: `""`
-Authentication protocol for authenticated SNMPv3 requests.
-
-* `auth_password`:
-Authentication password for authenticated SNMPv3 requests.
-
-* `sec_level`: Values: `"noAuthNoPriv"`,`"authNoPriv"`,`"authPriv"`. Default: `"noAuthNoPriv"`
-Security level used for SNMPv3 messages.
-
-* `context_name`:
-Context name used for SNMPv3 requests.
+```toml
+[[inputs.snmp]]
+  # ... snip ...
 
-* `priv_protocol`: Values: `"DES"`,`"AES"`,`""`. Default: `""`
-Privacy protocol used for encrypted SNMPv3 messages.
+  [[inputs.snmp.table]]
+    ## Object identifier of the SNMP table as a numeric or textual OID.
+    oid = "IF-MIB::ifTable"
 
-* `priv_password`:
-Privacy password used for encrypted SNMPv3 messages.
+    ## Name of the field or tag to create.  If not specified, it defaults to
+    ## the value of 'oid'.  If 'oid' is numeric an attempt to translate the
+    ## numeric OID into a textual OID will be made.
+    # name = ""
 
+    ## Which tags to inherit from the top-level config and to use in the output
+    ## of this table's measurement.
+    ## example: inherit_tags = ["source"]
+    # inherit_tags = []
 
-* `name`:
-Output measurement name.
+    ## Add an 'index' tag with the table row number.  Use this if the table has
+    ## no indexes or if you are excluding them.  This option is normally not
+    ## required as any index columns are automatically added as tags.
+    # index_as_tag = false
 
-#### Field parameters:
-* `oid`:
-OID to get. May be a numeric or textual OID.
+    [[inputs.snmp.table.field]]
+      ## OID to get. May be a numeric or textual module-qualified OID.
+      oid = "IF-MIB::ifDescr"
 
-* `oid_index_suffix`:
-The OID sub-identifier to strip off so that the index can be matched against other fields in the table.
+      ## Name of the field or tag to create.  If not specified, it defaults to
+      ## the value of 'oid'. If 'oid' is numeric an attempt to translate the
+      ## numeric OID into a textual OID will be made.
+      # name = ""
 
-* `oid_index_length`:
-Specifies the length of the index after the supplied table OID (in OID path segments). Truncates the index after this point to remove non-fixed value or length index suffixes.
+      ## Output this field as a tag.
+      # is_tag = false
 
-* `name`:
-Output field/tag name.
-If not specified, it defaults to the value of `oid`. If `oid` is numeric, an attempt to translate the numeric OID into a texual OID will be made.
+      ## The OID sub-identifier to strip off so that the index can be matched
+      ## against other fields in the table.
+      # oid_index_suffix = ""
 
-* `is_tag`:
-Output this field as a tag.
+      ## Specifies the length of the index after the supplied table OID (in OID
+      ## path segments). Truncates the index after this point to remove non-fixed
+      ## value or length index suffixes.
+      # oid_index_length = 0
+```
 
-* `conversion`: Values: `"float(X)"`,`"float"`,`"int"`,`""`. Default: `""`
-Converts the value according to the given specification.
+### Troubleshooting
 
-    - `float(X)`: Converts the input value into a float and divides by the Xth power of 10. Efficively just moves the decimal left X places. For example a value of `123` with `float(2)` will result in `1.23`.
-    - `float`: Converts the value into a float with no adjustment. Same as `float(0)`.
-    - `int`: Convertes the value into an integer.
-    - `hwaddr`: Converts the value to a MAC address.
-    - `ipaddr`: Converts the value to an IP address.
+Check that a numeric field can be translated to a textual field:
+```
+$ snmptranslate .1.3.6.1.2.1.1.3.0
+DISMAN-EVENT-MIB::sysUpTimeInstance
+```
 
-#### Table parameters:
-* `oid`:
-Automatically populates the table's fields using data from the MIB.
+Request a top-level field:
+```
+$ snmpget -v2c -c public 127.0.0.1 sysUpTime.0
+```
 
-* `name`:
-Output measurement name.
-If not specified, it defaults to the value of `oid`.  If `oid` is numeric, an attempt to translate the numeric OID into a texual OID will be made.
+Request a table:
+```
+$ snmptable -v2c -c public 127.0.0.1 ifTable
+```
 
-* `inherit_tags`:
-Which tags to inherit from the top-level config and to use in the output of this table's measurement.
+To collect a packet capture, run this command in the background while running
+Telegraf or one of the above commands.  Adjust the interface, host and port as
+needed:
+```
+$ sudo tcpdump -s 0 -i eth0 -w telegraf-snmp.pcap host 127.0.0.1 and port 161
+```
 
-* `index_as_tag`:
-Adds each row's index within the table as a tag.  
+### Example Output
 
-### MIB lookups
-If the plugin is configured such that it needs to perform lookups from the MIB, it will use the net-snmp utilities `snmptranslate` and `snmptable`.
+```
+snmp,agent_host=127.0.0.1,source=loaner uptime=11331974i 1575509815000000000
+interface,agent_host=127.0.0.1,ifDescr=wlan0,ifIndex=3,source=example.org ifAdminStatus=1i,ifInDiscards=0i,ifInErrors=0i,ifInNUcastPkts=0i,ifInOctets=3436617431i,ifInUcastPkts=2717778i,ifInUnknownProtos=0i,ifLastChange=0i,ifMtu=1500i,ifOperStatus=1i,ifOutDiscards=0i,ifOutErrors=0i,ifOutNUcastPkts=0i,ifOutOctets=581368041i,ifOutQLen=0i,ifOutUcastPkts=1354338i,ifPhysAddress="c8:5b:76:c9:e6:8c",ifSpecific=".0.0",ifSpeed=0i,ifType=6i 1575509815000000000
+interface,agent_host=127.0.0.1,ifDescr=eth0,ifIndex=2,source=example.org ifAdminStatus=1i,ifInDiscards=0i,ifInErrors=0i,ifInNUcastPkts=21i,ifInOctets=3852386380i,ifInUcastPkts=3634004i,ifInUnknownProtos=0i,ifLastChange=9088763i,ifMtu=1500i,ifOperStatus=1i,ifOutDiscards=0i,ifOutErrors=0i,ifOutNUcastPkts=0i,ifOutOctets=434865441i,ifOutQLen=0i,ifOutUcastPkts=2110394i,ifPhysAddress="c8:5b:76:c9:e6:8c",ifSpecific=".0.0",ifSpeed=1000000000i,ifType=6i 1575509815000000000
+interface,agent_host=127.0.0.1,ifDescr=lo,ifIndex=1,source=example.org ifAdminStatus=1i,ifInDiscards=0i,ifInErrors=0i,ifInNUcastPkts=0i,ifInOctets=51555569i,ifInUcastPkts=339097i,ifInUnknownProtos=0i,ifLastChange=0i,ifMtu=65536i,ifOperStatus=1i,ifOutDiscards=0i,ifOutErrors=0i,ifOutNUcastPkts=0i,ifOutOctets=51555569i,ifOutQLen=0i,ifOutUcastPkts=339097i,ifSpecific=".0.0",ifSpeed=10000000i,ifType=24i 1575509815000000000
+```
 
-When performing the lookups, the plugin will load all available MIBs. If your MIB files are in a custom path, you may add the path using the `MIBDIRS` environment variable. See [`man 1 snmpcmd`](http://net-snmp.sourceforge.net/docs/man/snmpcmd.html#lbAK) for more information on the variable.
+[net-snmp]: http://www.net-snmp.org/
+[man snmpcmd]: http://net-snmp.sourceforge.net/docs/man/snmpcmd.html#lbAK
+[metric filtering]: /docs/CONFIGURATION.md#metric-filtering
+[metric]: /docs/METRICS.md
diff --git a/plugins/inputs/snmp/snmp.go b/plugins/inputs/snmp/snmp.go
index fe9645772e3c8..75c9b7836e3a1 100644
--- a/plugins/inputs/snmp/snmp.go
+++ b/plugins/inputs/snmp/snmp.go
@@ -22,61 +22,46 @@ import (
 
 const description = `Retrieves SNMP values from remote agents`
 const sampleConfig = `
-  agents = [ "127.0.0.1:161" ]
-  ## Timeout for each SNMP query.
-  timeout = "5s"
-  ## Number of retries to attempt within timeout.
-  retries = 3
-  ## SNMP version, values can be 1, 2, or 3
-  version = 2
+  ## Agent addresses to retrieve values from.
+  ##   example: agents = ["udp://127.0.0.1:161"]
+  ##            agents = ["tcp://127.0.0.1:161"]
+  agents = ["udp://127.0.0.1:161"]
+
+  ## Timeout for each request.
+  # timeout = "5s"
+
+  ## SNMP version; can be 1, 2, or 3.
+  # version = 2
 
   ## SNMP community string.
-  community = "public"
-
-  ## The GETBULK max-repetitions parameter
-  max_repetitions = 10
-
-  ## SNMPv3 auth parameters
-  #sec_name = "myuser"
-  #auth_protocol = "md5"      # Values: "MD5", "SHA", ""
-  #auth_password = "pass"
-  #sec_level = "authNoPriv"   # Values: "noAuthNoPriv", "authNoPriv", "authPriv"
-  #context_name = ""
-  #priv_protocol = ""         # Values: "DES", "AES", ""
-  #priv_password = ""
-
-  ## measurement name
-  name = "system"
-  [[inputs.snmp.field]]
-    name = "hostname"
-    oid = ".1.0.0.1.1"
-  [[inputs.snmp.field]]
-    name = "uptime"
-    oid = ".1.0.0.1.2"
-  [[inputs.snmp.field]]
-    name = "load"
-    oid = ".1.0.0.1.3"
-  [[inputs.snmp.field]]
-    oid = "HOST-RESOURCES-MIB::hrMemorySize"
-
-  [[inputs.snmp.table]]
-    ## measurement name
-    name = "remote_servers"
-    inherit_tags = [ "hostname" ]
-    [[inputs.snmp.table.field]]
-      name = "server"
-      oid = ".1.0.0.0.1.0"
-      is_tag = true
-    [[inputs.snmp.table.field]]
-      name = "connections"
-      oid = ".1.0.0.0.1.1"
-    [[inputs.snmp.table.field]]
-      name = "latency"
-      oid = ".1.0.0.0.1.2"
-
-  [[inputs.snmp.table]]
-    ## auto populate table's fields using the MIB
-    oid = "HOST-RESOURCES-MIB::hrNetworkTable"
+  # community = "public"
+
+  ## Number of retries to attempt.
+  # retries = 3
+
+  ## The GETBULK max-repetitions parameter.
+  # max_repetitions = 10
+
+  ## SNMPv3 authentication and encryption options.
+  ##
+  ## Security Name.
+  # sec_name = "myuser"
+  ## Authentication protocol; one of "MD5", "SHA", or "".
+  # auth_protocol = "MD5"
+  ## Authentication password.
+  # auth_password = "pass"
+  ## Security Level; one of "noAuthNoPriv", "authNoPriv", or "authPriv".
+  # sec_level = "authNoPriv"
+  ## Context Name.
+  # context_name = ""
+  ## Privacy protocol used for encrypted messages; one of "DES", "AES" or "".
+  # priv_protocol = ""
+  ## Privacy password used for encrypted messages.
+  # priv_password = ""
+
+  ## Add fields and tables defining the variables you wish to collect.  This
+  ## example collects the system uptime and interface variables.  Reference the
+  ## full plugin documentation for configuration details.
 `
 
 // execCommand is so tests can mock out exec.Command usage.
@@ -108,41 +93,42 @@ func execCmd(arg0 string, args ...string) ([]byte, error) {
 
 // Snmp holds the configuration for the plugin.
 type Snmp struct {
-	// The SNMP agent to query. Format is ADDR[:PORT] (e.g. 1.2.3.4:161).
-	Agents []string
+	// The SNMP agent to query. Format is [SCHEME://]ADDR[:PORT] (e.g.
+	// udp://1.2.3.4:161).  If the scheme is not specified then "udp" is used.
+	Agents []string `toml:"agents"`
 	// Timeout to wait for a response.
-	Timeout internal.Duration
-	Retries int
+	Timeout internal.Duration `toml:"timeout"`
+	Retries int               `toml:"retries"`
 	// Values: 1, 2, 3
-	Version uint8
+	Version uint8 `toml:"version"`
 
 	// Parameters for Version 1 & 2
-	Community string
+	Community string `toml:"community"`
 
 	// Parameters for Version 2 & 3
-	MaxRepetitions uint8
+	MaxRepetitions uint8 `toml:"max_repetitions"`
 
 	// Parameters for Version 3
-	ContextName string
+	ContextName string `toml:"context_name"`
 	// Values: "noAuthNoPriv", "authNoPriv", "authPriv"
-	SecLevel string
-	SecName  string
+	SecLevel string `toml:"sec_level"`
+	SecName  string `toml:"sec_name"`
 	// Values: "MD5", "SHA", "". Default: ""
-	AuthProtocol string
-	AuthPassword string
+	AuthProtocol string `toml:"auth_protocol"`
+	AuthPassword string `toml:"auth_password"`
 	// Values: "DES", "AES", "". Default: ""
-	PrivProtocol string
-	PrivPassword string
-	EngineID     string
-	EngineBoots  uint32
-	EngineTime   uint32
+	PrivProtocol string `toml:"priv_protocol"`
+	PrivPassword string `toml:"priv_password"`
+	EngineID     string `toml:"-"`
+	EngineBoots  uint32 `toml:"-"`
+	EngineTime   uint32 `toml:"-"`
 
 	Tables []Table `toml:"table"`
 
 	// Name & Fields are the elements of a Table.
 	// Telegraf chokes if we try to embed a Table. So instead we have to embed the
 	// fields of a Table, and construct a Table during runtime.
-	Name   string
+	Name   string  // deprecated in 1.14; use name_override
 	Fields []Field `toml:"field"`
 
 	connectionCache []snmpConnection
diff --git a/plugins/inputs/snmp/snmp_test.go b/plugins/inputs/snmp/snmp_test.go
index 9a4335e4edf8f..3e174e2243039 100644
--- a/plugins/inputs/snmp/snmp_test.go
+++ b/plugins/inputs/snmp/snmp_test.go
@@ -10,6 +10,7 @@ import (
 	"time"
 
 	"github.com/influxdata/telegraf/internal"
+	"github.com/influxdata/telegraf/plugins/inputs"
 	"github.com/influxdata/telegraf/testutil"
 	"github.com/influxdata/toml"
 	"github.com/soniah/gosnmp"
@@ -82,45 +83,20 @@ var tsc = &testSNMPConnection{
 }
 
 func TestSampleConfig(t *testing.T) {
-	conf := struct {
-		Inputs struct {
-			Snmp []*Snmp
-		}
-	}{}
-	err := toml.Unmarshal([]byte("[[inputs.snmp]]\n"+(*Snmp)(nil).SampleConfig()), &conf)
-	assert.NoError(t, err)
+	conf := inputs.Inputs["snmp"]()
+	err := toml.Unmarshal([]byte(conf.SampleConfig()), conf)
+	require.NoError(t, err)
 
-	s := Snmp{
-		Agents:         []string{"127.0.0.1:161"},
+	expected := &Snmp{
+		Agents:         []string{"udp://127.0.0.1:161"},
 		Timeout:        internal.Duration{Duration: 5 * time.Second},
 		Version:        2,
 		Community:      "public",
 		MaxRepetitions: 10,
 		Retries:        3,
-
-		Name: "system",
-		Fields: []Field{
-			{Name: "hostname", Oid: ".1.0.0.1.1"},
-			{Name: "uptime", Oid: ".1.0.0.1.2"},
-			{Name: "load", Oid: ".1.0.0.1.3"},
-			{Oid: "HOST-RESOURCES-MIB::hrMemorySize"},
-		},
-		Tables: []Table{
-			{
-				Name:        "remote_servers",
-				InheritTags: []string{"hostname"},
-				Fields: []Field{
-					{Name: "server", Oid: ".1.0.0.0.1.0", IsTag: true},
-					{Name: "connections", Oid: ".1.0.0.0.1.1"},
-					{Name: "latency", Oid: ".1.0.0.0.1.2"},
-				},
-			},
-			{
-				Oid: "HOST-RESOURCES-MIB::hrNetworkTable",
-			},
-		},
+		Name:           "snmp",
 	}
-	assert.Equal(t, &s, conf.Inputs.Snmp[0])
+	require.Equal(t, expected, conf)
 }
 
 func TestFieldInit(t *testing.T) {
diff --git a/plugins/inputs/snmp_trap/README.md b/plugins/inputs/snmp_trap/README.md
index 8c1a2c132adc7..ceb370d8f65e0 100644
--- a/plugins/inputs/snmp_trap/README.md
+++ b/plugins/inputs/snmp_trap/README.md
@@ -6,13 +6,22 @@ notifications (traps and inform requests).
 Notifications are received on plain UDP. The port to listen is
 configurable.
 
-OIDs can be resolved to strings using system MIB files. This is done
-in same way as the SNMP input plugin. See the section "MIB Lookups" in
-the SNMP [README.md](../snmp/README.md) for details.
+### Prerequisites
+
+This plugin uses the `snmptranslate` programs from the
+[net-snmp][] project.  These tools will need to be installed into the `PATH` in
+order to be located.  Other utilities from the net-snmp project may be useful
+for troubleshooting, but are not directly used by the plugin.
+
+These programs will load available MIBs on the system.  Typically the default
+directory for MIBs is `/usr/share/snmp/mibs`, but if your MIBs are in a
+different location you may need to make the paths known to net-snmp.  The
+location of these files can be configured in the `snmp.conf` or via the
+`MIBDIRS` environment variable. See [`man 1 snmpcmd`][man snmpcmd] for more
+information.
 
 ### Configuration
 ```toml
-# Snmp trap listener
 [[inputs.snmp_trap]]
   ## Transport, local address, and port to listen on.  Transport must
   ## be "udp://".  Omit local address to listen on all interfaces.
@@ -26,27 +35,7 @@ the SNMP [README.md](../snmp/README.md) for details.
   # timeout = "5s"
 ```
 
-### Metrics
-
-- snmp_trap
-  - tags:
-	- source (string, IP address of trap source)
-	- name (string, value from SNMPv2-MIB::snmpTrapOID.0 PDU)
-	- mib (string, MIB from SNMPv2-MIB::snmpTrapOID.0 PDU)
-	- oid (string, OID string from SNMPv2-MIB::snmpTrapOID.0 PDU)
-	- version (string, "1" or "2c" or "3")
-  - fields:
-	- Fields are mapped from variables in the trap. Field names are
-      the trap variable names after MIB lookup. Field values are trap
-      variable values.
-
-### Example Output
-```
-snmp_trap,mib=SNMPv2-MIB,name=coldStart,oid=.1.3.6.1.6.3.1.1.5.1,source=192.168.122.102,version=2c snmpTrapEnterprise.0="linux",sysUpTimeInstance=1i 1574109187723429814
-snmp_trap,mib=NET-SNMP-AGENT-MIB,name=nsNotifyShutdown,oid=.1.3.6.1.4.1.8072.4.0.2,source=192.168.122.102,version=2c sysUpTimeInstance=5803i,snmpTrapEnterprise.0="netSnmpNotificationPrefix" 1574109186555115459
-```
-
-### Using a Privileged Port
+#### Using a Privileged Port
 
 On many operating systems, listening on a privileged port (a port
 number less than 1024) requires extra permission.  Since the default
@@ -70,3 +59,26 @@ setcap cap_net_bind_service=+ep /usr/bin/telegraf
 
 On Mac OS, listening on privileged ports is unrestricted on versions
 10.14 and later.
+
+### Metrics
+
+- snmp_trap
+  - tags:
+	- source (string, IP address of trap source)
+	- name (string, value from SNMPv2-MIB::snmpTrapOID.0 PDU)
+	- mib (string, MIB from SNMPv2-MIB::snmpTrapOID.0 PDU)
+	- oid (string, OID string from SNMPv2-MIB::snmpTrapOID.0 PDU)
+	- version (string, "1" or "2c" or "3")
+  - fields:
+	- Fields are mapped from variables in the trap. Field names are
+      the trap variable names after MIB lookup. Field values are trap
+      variable values.
+
+### Example Output
+```
+snmp_trap,mib=SNMPv2-MIB,name=coldStart,oid=.1.3.6.1.6.3.1.1.5.1,source=192.168.122.102,version=2c snmpTrapEnterprise.0="linux",sysUpTimeInstance=1i 1574109187723429814
+snmp_trap,mib=NET-SNMP-AGENT-MIB,name=nsNotifyShutdown,oid=.1.3.6.1.4.1.8072.4.0.2,source=192.168.122.102,version=2c sysUpTimeInstance=5803i,snmpTrapEnterprise.0="netSnmpNotificationPrefix" 1574109186555115459
+```
+
+[net-snmp]: http://www.net-snmp.org/
+[man snmpcmd]: http://net-snmp.sourceforge.net/docs/man/snmpcmd.html#lbAK