SNMP(Application)
β¨ NAME β¨
SNMP(Application) from Ericsson AB, bestie. This manual? It's literally the SNMP Application. π
π DESCRIPTION π
π¦ Description π¦
okay so this chapter spills all the tea about the snmp application in OTP. The SNMP application is serving:
- multilingual extensible SNMP agent π
- SNMP manager π
- MIB compiler β¨
π Configuration π
These are the configuration parameters defined for the SNMP application. Wanna know more about config parameters? Go check application(3). π«Ά
The snmp part of the config file that specifies these parameters is basically this tuple:
{snmp, snmp_components_config()}
A minimal config file for starting a node with both a manager and an agent? It's giving:
[{snmp,
[{agent, [{db_dir, "/tmp/snmp/agent/db"},
{config, [{dir, "/tmp/snmp/agent/conf"}]}]},
{manager, [{config, [{dir, "/tmp/snmp/manager/conf"},
{db_dir, "/tmp/snmp/manager/db"}]}]}]}
]
}
].
Every snmp component has its own set of configuration parameters, even though some types are shared between both components.
snmp_components_config() -> [snmp_component_config()]
snmp_component_config() -> {agent, agent_options()} | {manager, manager_options()}
agent_options() = [agent_option()]
agent_option() = {restart_type, restart_type()} |
{agent_type, agent_type()} |
{agent_verbosity, verbosity()} |
{discovery, agent_discovery()} |
{versions, versions()} |
{gb_max_vbs, gb_max_vbs()} |
{priority, priority()} |
{multi_threaded, multi_threaded()} |
{db_dir, db_dir()} |
{db_init_error, db_init_error()} |
{local_db, local_db()} |
{net_if, agent_net_if()} |
{mibs, mibs()} |
{mib_storage, mib_storage()} |
{mib_server, mib_server()} |
{audit_trail_log, audit_trail_log()} |
{error_report_mod, error_report_mod()} |
{note_store, note_store()} |
{symbolic_store, symbolic_store()} |
{target_cache, target_cache()} |
{config, agent_config()}
manager_options() = [manager_option()]
manager_option() = {restart_type, restart_type()} |
{net_if, manager_net_if()} |
{server, server()} |
{note_store, note_store()} |
{config, manager_config()} |
{inform_request_behaviour, manager_irb()} |
{mibs, manager_mibs()} |
{priority, priority()} |
{audit_trail_log, audit_trail_log()} |
{versions, versions()} |
{def_user_mod, def_user_module() |
{def_user_data, def_user_data()}
Agent specific config options and types:
agent_type() = master | sub <optional>β If it'smaster, one master agent is started. Otherwise, no agents are started. Default ismaster. πagent_discovery() = [agent_discovery_opt()] <optional>β withagent_discovery_opt() = {terminating, agent_terminating_discovery_opts()} | {originating, agent_originating_discovery_opts()}. Theterminatingoptions affect discovery initiated by a manager. Theoriginatingoptions affect discovery initiated by this agent. For defaults, see the options inagent_discovery_opt().agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>β withagent_terminating_discovery_opt() = {enable, boolean()} | {stage2, discovery | plain} | {trigger_username, string()}. These are options affecting discovery terminating in this agent (i.e. initiated by a manager). The default values for the terminating discovery options are:enable:truestage2:discoverytrigger_username:""
agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>β withagent_originating_discovery_opt() = {enable, boolean()}. These are options affecting discovery originating in this agent. The default values for the originating discovery options are:enable:true
multi_threaded() = bool() | extended <optional>β Iftrue(orextended), the agent is multi-threaded, with one thread for each get request. Theextendedvalue means that a special 'process' is also created intended to handle all notifications.trueβ One worker dedicated to 'set-requests' and one (main) worker for all other requests ('get-request' and notifications). If the 'main' worker is busy, a temporary process is spawned to handle that job ('get-request' or notification).extendedβ One worker dedicated to 'set-requests', one worker dedicated to notifications, and one (main) worker for all 'get-requests'. If the 'main' worker is busy, a temporary process is spawned to handle that 'get-request'.
β οΈ NOTE: Even with multi-threaded set to extended there is still a risk for 'reorder' when sending inform-requsts, which require a response (and may therefore require resending). Also, there is of course no way to guarantee order once the package is on the network.
Default is false.
db_dir() = string() <mandatory>β Defines where the SNMP agent internal db files are stored. (Mandatory, bestie β no skips.) πgb_max_vbs() = pos_integer() | infinity <optional>β Defines the max number of varbinds allowed in a Get-BULK response. Default is1000.local_db() = [local_db_opt()] <optional>β withlocal_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}. Defines options specific for the SNMP agent local database. For defaults, see the options inlocal_db_opt().agent_repair() = false | true | force <optional>β When startingsnmpa_local_db, it always tries to open an existing database. Iffalse, and some errors occur, a new database is created instead. Iftrue, an existing file will be repaired. Ifforce, the table will be repaired even if it was properly closed. Default istrue.agent_auto_save() = integer() | infinity <optional>β The auto save interval. The table is flushed to disk whenever not accessed for this amount of time. Default is5000.agent_net_if() = [agent_net_if_opt()] <optional>β withagent_net_if_opt() = {module, agent_net_if_module()} | {verbosity, verbosity()} | {options, agent_net_if_options()}. Defines options specific for the SNMP agent network interface entity. For defaults, see the options inagent_net_if_opt().agent_net_if_module() = atom() <optional>β Module which handles the network interface part for the SNMP agent. Must implement thesnmpa_network_interfacebehaviour. Default issnmpa_net_if.agent_net_if_options() = [agent_net_if_option()] <optional>β withagent_net_if_option() = {bind_to, bind_to()} | {sndbuf, sndbuf()} | {recbuf, recbuf()} | {no_reuse, no_reuse()} | {req_limit, req_limit()} | {filter, agent_net_if_filter_options()} | {open_err_filters, agent_net_if_open_err_filters()} | {extra_sock_opts, extra_socket_options()} | {inet_backend, inet_backend()}. These options are actually specific to the used module. The ones shown here are applicable to the defaultagent_net_if_module().
NOTE: If the user has configured transports with options then those will take precedence over these options. See agent information for more info.
For defaults, see the options in agent_net_if_option().
req_limit() = integer() | infinity <optional>β Max number of simultaneous requests handled by the agent. Default isinfinity.agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>β withagent_net_if_filter_option() = {module, agent_net_if_filter_module()}. These options are actually specific to the used module. The ones shown here are applicable to the defaultagent_net_if_filter_module(). For defaults, see the options inagent_net_if_filter_option().agent_net_if_filter_module() = atom() <optional>β Module which handles the network interface filter part for the SNMP agent. Must implement thesnmpa_network_interface_filterbehaviour. Default issnmpa_net_if_filter.agent_net_if_open_err_filters() = [agent_net_if_open_err_filter()] <optional>β withagent_net_if_open_err_filter() = atom(). During agent initiation, the transports UDP sockets are opened. If this operation fails, the net-if (and the agent) fails to start (crash). This (filter) list contains error (reasons) that will make net-if fail "nicely". This (filter) list is supposed to contain errors that can be returned bygen_udp:open/1,2. The effect is that any error returned bygen_udp:openwhich are in this list will be considered "non-fatal" and will only result in an info message, rather than an error message. Net If, and the agent, will still crash, but will produce a less obnoxious message. πagent_mibs() = [string()] <optional>β Specifies a list of MIBs (including path) that defines which MIBs are initially loaded into the SNMP master agent. Note that the following mibs will always be loaded:- version v1:
STANDARD-MIB - version v2:
SNMPv2 - version v3:
SNMPv2,SNMP-FRAMEWORK-MIBandSNMP-MPD-MIBDefault is[].
- version v1:
mib_storage() = [mib_storage_opt()] <optional>β withmib_storage_opt() = {module, mib_storage_module()} | {options, mib_storage_options()}. This option specifies how basic mib data is stored. This option is used by two parts of the snmp agent: The mib-server and the symbolic-store. Default is[{module, snmpa_mib_storage_ets}].mib_storage_module()=snmpa_mib_data_ets|snmpa_mib_data_dets|snmpa_mib_data_mnesia|module()β this sets the mib storage module for the SNMP agent, exactly as thesnmpa_mib_storagebehaviour defines it. πΎ
Several entities hanging around the agent (the mib-server, via its data module, and the symbolic-store) use this thing to stash all the miscellaneous mib-related data they picked up while loading a mib.
The agent ships with a few implementations already, no assembly required:
snmpa_mib_storage_etssnmpa_mib_storage_detssnmpa_mib_storage_mnesia
The default module is snmpa_mib_storage_ets. π
mib_storage_options()=list()optional β this one is implementation dependent, bestie. Like, it literally depends on which module you're using. Each module has its own valid option set. For the modules that come with the app, here's what's supported: π«Άsnmpa_mib_storage_ets:{dir, filename()} | {action, keep | clear},{checksum, boolean()}dirβ if you set it, it points at a directory where a file lives, and all the data in the ets table gets "synced" to that file. Also, when a table is opened, this file gets read, if it exists. By default this is not used.actionβ tells the thing what to do when it finds a non-empty file: keep its content, or clear it out. Default iskeep.checksumβ decides whether the file is checksummed or not. Default isfalse.
snmpa_mib_storage_dets:{dir, filename()} | {action, keep | clear},{auto_save, default | pos_integer()} | {repair, force | boolean()}dirβ this one is mandatory, no skipping it. Points to the directory where the dets table's file goes.actionβ what to do when a non-empty file is found: keep its content or clear it out. Default iskeep.auto_saveβ sets the dets auto-save frequency. Default isdefault.repairβ sets the dets repair behaviour. Default isfalse.
snmpa_mib_storage_mnesia:{action, keep | clear},{nodes, [node()]}actionβ what to do when there's a non-empty, already-existing table: keep its content or clear it out. Default iskeep.nodesβ a list of node names (or an atom describing a list of nodes) saying where to open the table. And it's on you to make sure mnesia is actually running on those nodes, so like, do check. π
These distinct values are recognised:
[]β gets translated into a list of your own node:[node()]allβerlang:nodes()visibleβerlang:nodes(visible)connectedβerlang:nodes(connected)db_nodesβmnesia:system_info(db_nodes)
Default is the result of the call: erlang:nodes().
mib_server()=[mib_server_opt()]optionalmib_server_opt()={mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()} | {data_module, mib_server_data_module()}
These are the options that belong specifically to the SNMP agent mib server. For the defaults, look at the options inside mib_server_opt(). π
mibentry_override()=bool()optional β if this isfalse, then every time a mib is loaded, each mib-entry gets checked before the mib is installed. The whole point of that check? Stopping the same symbolic mibentry name from being used for different oid's. Default isfalse.trapentry_override()=bool()optional β if this isfalse, then when a mib is loaded, each trap gets checked before the mib gets installed. That check exists so the same symbolic trap name can't be used for different trap's. Default isfalse.mib_server_data_module()=snmpa_mib_data_tttn | module()optional β defines the backend data module of the SNMP agent mib-server, as defined by thesnmpa_mib_databehaviour. At the moment, the only module the agent ships with is the default one:snmpa_mib_data_tttn. Default module issnmpa_mib_data_tttn.mibs_cache()=bool() | mibs_cache_opts()optional β should the agent use the mib server lookup cache or not, that's the question. β¨ Default istrue(and in that case, themibs_cache_opts()default values apply).mibs_cache_opts()=[mibs_cache_opt()]optionalmibs_cache_opt()={autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}
Options specific to the SNMP agent mib server cache. For the defaults, peep the options inside mibs_cache_opt().
mibs_cache_autogc()=bool()optional β says whether the mib server does cache gc on its own, or leaves it to you (seegc_mibs_cache/0,1,2,3). Default istrue.mibs_cache_age()=integer() > 0optional β how old the entries in the cache are allowed to get before they get GC'ed (assuming a GC happens at all). Every entry in the cache gets "touched" whenever it's accessed, so it's giving very much a freshness vibe. The age is measured in milliseconds. Default is 10 timutes. π (yes, that is genuinely how it's spelled in here, we don't gatekeep typos π«Ά)mibs_cache_gclimit()=infinity | integer() > 0optional β when a GC is running, this is the max number of cache entries that get deleted from the cache.
Why would anyone even want a limit? Okay so, if the cache is large, a GC can potentially take a long ass time, and the agent is "busy" that whole while. But on a heavily loaded system, we also risk not removing enough elements from the cache, which instead makes it grow over time. That's exactly why the default value is infinity, which makes sure all candidates get removed as soon as possible. Default is infinity. π
error_report_mod()=atom()optional β defines an error report module that implements thesnmpa_error_reportbehaviour. Two modules come with the toolkit:snmpa_error_loggerandsnmpa_error_io. Default issnmpa_error_logger. π¨symbolic_store()=[symbolic_store_opt()]symbolic_store_opt()={verbosity, verbosity()}
Options specific to the SNMP agent symbolic store. For the defaults, see the options in symbolic_store_opt().
target_cache()=[target_cache_opt()]target_cache_opt()={verbosity, verbosity()}
Options specific to the SNMP agent target cache. For the defaults, see the options in target_cache_opt().
agent_config()=[agent_config_opt()]mandatory β like, you actually have to give this one bestie. π€agent_config_opt()={dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}
Config-related options specific to the SNMP agent. For the defaults, see the options in agent_config_opt().
agent_config_dir=dir()mandatory β says where the SNMP agent configuration files are stored.force_load()=bool()optional β iftrue, the configuration files get re-read during start-up and the contents of the configuration database get ignored. Which means: if it'strue, any changes to the configuration database are lost the moment the agent reboots. β οΈ Default isfalse.
Manager specific config options and types: π
server()=[server_opt()]optionalserver_opt()={timeout, server_timeout()} | {verbosity, verbosity()} | {cbproxy, server_cbproxy()} | {netif_sup, server_nis()}
Specifies the options for the manager server process. Default is silence. π€« (iconic default name honestly)
server_timeout()=integer()optional β this is the asynchronous request cleanup time. For every request, some info gets stored internally so the reply can be delivered to the right destination when it shows up. If the reply arrives, that info gets deleted. But if there's no reply (in time), the info has to be deleted once the best-before time has passed. This cleanup runs at regular intervals, defined by theserver_timeout()time. The information has a best-before time, defined by the Expire time you give when calling the request function (seeasync_get,async_get_nextandasync_set). Time is in milli-seconds. Default is30000.server_cbproxy()=temporary (default) | permanentoptional β this option says how the server handles callback calls. πtemporary (default)β a temporary process gets created for each callback call.permanentβ with this, the server creates a permanent (named) process that in effect serializes all callback calls.
Default is temporary.
server_nis()=none (default) | {PingTO, PongTO}optional β this option says whether the server should actively supervise the net-if process. Heads up though: this only works if the net-if process actually supports the protocol. More info lives in thesnmpm_network_interfacebehaviour. πnone (default)β no active supervision of the net-if process.{PingTO :: pos_integer(), PongTO :: pos_integer()}β thePingTOtime specifies the time between a successful ping (or start) and the moment a ping message gets sent to the net-if process (basically, the time between pings). ThePongTOtime specifies how long the net-if process has to respond to a ping message with a pong message. It starts counting when the ping message has been sent. Both times are in milli seconds.
Default is none.
manager_config()=[manager_config_opt()]mandatory β yes, also required, no negotiating. πmanager_config_opt()={dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}
Config-related options specific to the SNMP manager. For the defaults, see the options in manager_config_opt().
manager_config_dir=dir()mandatory β says where the SNMP manager configuration files are stored.manager_db_dir=dir()mandatory β says where the SNMP manager store keeps its persistent data.manager_repair()=false | true | forceoptional β defines the repair option for the persistent database, like if and how the table gets repaired when it's opened. Default istrue. π§manager_auto_save()=integer() | infinityoptional β the auto save interval. The table gets flushed to disk whenever it hasn't been accessed for this amount of time. Default is5000.manager_irb()=auto | user | {user, integer()}optional β this option defines how the manager handles sending responses (acknowledgments) to inform-requests it receives.autoβ the manager will autonomously send a response (acknowledgment) to inform-request messages.
{user, integer()}β okay so when thehandle_informfunction is done doing its thing π , the manager is gonna send a response (that's the acknowledgment, bestie) back to the inform-request messages. That integer? It's the amount of time in milli-seconds that the manager thinks the stored inform-request info is still valid for.userβ literally the same as{user, integer()}except it just uses the default time, which is 15 seconds (15000). Chill of it.
Wanna know more? Peek at snmpm_network_interface, handle_inform, and the definition of the manager net if π«Ά.
Default is auto.
manager_mibs() = [string()]<optional>β this one gives you a list of MIBs (paths included, obviously πΈ) and decides which MIBs get loaded into the SNMP manager from the jump.
Default is [].
manager_net_if() = [manager_net_if_opt()]<optional>manager_net_if_opt() = {module, manager_net_if_module()} | {verbosity, verbosity()} | {options, manager_net_if_options()}
This is where you define the options that are specific to the SNMP manager's network interface entity β¨.
Wanna know the defaults? They're in the options in manager_net_if_opt().
manager_net_if_options() = [manager_net_if_option()]<optional>manager_net_if_option() = {bind_to, bind_to()} | {sndbuf, sndbuf()} | {recbuf, recbuf()} | {no_reuse, no_reuse()} | {filter, manager_net_if_filter_options()} | {extra_sock_opts, extra_socket_options()}} | {inet_backend, inet_backend()}
These options are lowkey specific to the module you're using. The ones listed right here apply to the default manager_net_if_module() π.
Wanna know the defaults? They're in the options in manager_net_if_option().
manager_net_if_module() = atom()<optional>β the module that handles the network interface part for the SNMP manager. It has to implement thesnmpm_network_interfacebehaviour fr fr.
Default is snmpm_net_if.
manager_net_if_filter_options() = [manager_net_if_filter_option()]<optional>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}
These are specific to the module you're using too. The ones shown apply to the default manager_net_if_filter_module() π.
For defaults, look at the options in manager_net_if_filter_option().
manager_net_if_filter_module() = atom()<optional>β the module that handles the network interface filter part for the SNMP manager. It has to implement thesnmpm_network_interface_filterbehaviour π.
Default is snmpm_net_if_filter.
def_user_module() = atom()<optional>β the module that implements the default user. Peep thesnmpm_userbehaviour for the tea β.
Default is snmpm_user_default.
def_user_data() = term()<optional>β data for the default user. It gets passed to the user module whenever the callback functions get called π.
Default is undefined.
π§© Common config types π§©
restart_type() = permanent | transient | temporaryβ check the supervisor docs for more deets π.
Default is permanent for the agent and transient for the manager.
db_init_error() = terminate | create | create_db_and_dirβ this one decides what happens if the agent or manager can't open an existing database file π.terminatemeans the agent/manager is just gonna dip and terminate.createmeans it's gonna yeet the faulty file(s) and make brand new ones. Andcreate_db_and_dirmeans it's gonna create the database file and any missing parent directories for it, bestie πΈ.
Default is terminate.
priority() = atom()<optional>β sets the Erlang priority for every single SNMP process ποΈ.
Default is normal.
versions() = [version()]<optional>version() = v1 | v2 | v3
Which SNMP versions are allowed in / get used π.
Default is [v1,v2,v3].
verbosity() = silence | info | log | debug | trace<optional>β the verbosity level for a SNMP process. Basically it says how much debug info gets printed π¨οΈ.
Default is silence.
bind_to() = bool()<optional>β iftrue,net_ifbinds to the IP address. Iffalse,net_iflistens on any IP address on the host where it's chillin' ποΈ.
Default is false.
no_reuse() = bool()<optional>β iftrue,net_ifdoesn't say that the IP and port address should be reusable. Iffalse, the address is set to reusable β»οΈ.
Default is false.
recbuf() = integer()<optional>β the receive buffer size π₯.
Default value is defined by gen_udp.
sndbuf() = integer()<optional>β the send buffer size π€.
Default value is defined by gen_udp.
extra_socket_options() = list()<optional>β a list of arbitrary socket options π². snmp does not inspect this list (other than just checking that it is a list π). It's on you to make sure these are valid options and don't clash with the "normal" ones, I'm serious bestie π.
Default is [].
inet_backend() = inet | socket<optional>β picks the inet-backend π. This option makes it possible to usenet_if(gen_udp) with a different inet-backend ('inet'or'socket').
Default is inet.
note_store() = [note_store_opt()]<optional>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}
Sets the start-up verbosity for the SNMP note store π.
For defaults, peep the options in note_store_opt().
note_store_timeout() = integer()<optional>β note cleanup time β°. Whenever you store a note in the note store, each note gets a lifetime. Every timeout, thenote_storeprocess does a GC to yeet the expired notes outta there ποΈ. Time is in milli-seconds.
Default is 30000.
audit_trail_log() = [audit_trail_log_opt()]<optional>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}
If this is present, it sets the options for audit trail logging π. The disk_log module is used to keep a wrap log going. And if it's present, the dir and size options are mandatory β no skipping, bestie π. If it's not present, audit trail logging just... isn't used at all.
atl_type() = read | write | read_write<optional>β specifies what kind of audit trail log to use π. The actual effect of the type is different for the agent vs the manager, iykyk.
For the agent:
- if
writeis specified, only set requests get logged. - if
readis specified, only get requests get logged. - if
read_write, all requests get logged.
For the manager:
- if
writeis specified, only sent messages get logged. - if
readis specified, only received messages get logged. - if
read_write, both outgoing and incoming messages get logged π.
Default is read_write.
atl_dir = dir()<mandatory>β specifies where the audit trail log gets stored π. Ifaudit_trail_logsays logging should happen, this parameter must be defined. Periodt.atl_size() = {integer(), integer()}<mandatory>β specifies the size of the audit trail log π. This parameter gets sent todisk_log. Ifaudit_trail_logsays logging should happen, this parameter must be defined.atl_repair() = true | false | truncate | snmp_repair<optional>β says whether (and how) the audit trail log gets repaired when it's opened π§. As long as this parameter isn'tsnmp_repair, it gets sent todisk_log. But if the value issnmp_repair? snmp tries to handle certain faults all by itself πͺ. And even if it can't repair the file, it doesn't just truncate it right away β instead it moves it aside for later off-line analysis. Slay.
Default is true.
atl_seqno() = true | false<optional>β says whether the audit trail log entries get (sequence) numbered or not π’. The range of the sequence numbers follows RFC 5424, so like1through2147483647.
Default is false.
π See Also π
And that's the whole page, bestie β this is the snmp manual, version 5.20.5, page 6 of the SNMP(Application) docs, and you just ate all of it π
β¨π go off, fr fr π«Άπ¦πΈ
π¦ where this page comes from
- arch rolling: erlang-core 29.1.1-1 Β· Apache-2.0
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms