The module snmpm
contains interface functions to the
SNMP manager.
The following datatypes are used in the functions below:
oid() = [byte()]
snmp_reply() = {error_status(), error_index(), varbinds()}
error_status() = noError | atom()
error_index() = integer()
varbinds() = [varbind()]
The oid()
type is used to represent an ASN.1 OBJECT
IDENTIFIER.
Types:
Ref = reference()
Monitor the SNMP manager. In case of a crash, the calling (monitoring) process will get a 'DOWN' message (see the erlang module for more info).
Types:
Ref = reference()
notify_started(Timeout) -> Pid
Types:
Timeout = integer()
Pid = pid()
Request a notification (message) when the SNMP manager has started.
The Timeout
is the time the request is valid. The
value has to be greater then zero.
The Pid
is the process handling the supervision of the
SNMP manager start. When the manager has started a completion
message will be sent to the client from this process:
{snmpm_started, Pid}
. If the SNMP manager was not started
in time, a timeout message will be sent to the client:
{snmpm_start_timeout, Pid}
.
A client application that is dependent on the SNMP manager will use this function in order to be notified of when the manager has started. There are two situtations when this is useful:
The function returnes the pid() of a handler process, that does the supervision on behalf of the client application. Note that the client application is linked to this handler.
This function is used in conjuction with the monitor function.
cancel_notify_started(Pid) -> void()
Types:
Pid = pid()
register_user(Id, Module, Data) -> ok | {error, Reason}
Types:
Id = term()
Module = snmpm_user()
Data = term()
Reason = term()
snmpm_user() = Module implementing the snmpm_user behaviour
Register the manager entity (=user) responsible for specific agent(s).
Module
is the callback module (snmpm_user behaviour) which
will be called whenever something happens (detected
agent, incomming reply or incomming trap/notification).
Note that this could have already been done as a
consequence of the node config. (see users.conf).
register_user_monitor(Id, Module, Data) -> ok | {error, Reason}
Types:
Id = term()
Module = snmpm_user()
Data = term()
Reason = term()
snmpm_user() = Module implementing the snmpm_user behaviour
Register the monitored manager entity (=user) responsible for specific agent(s).
The process performing the registration will be monitored. Which means that if that process should die, all agents registered by that user process will be unregistered. All outstanding requsts will be canceled.
Module
is the callback module (snmpm_user behaviour) which
will be called whenever something happens (detected
agent, incomming reply or incomming trap/notification).
Note that this could have already been done as a
consequence of the node config. (see users.conf).
unregister_user(Id) -> ok | {error, Reason}
Types:
Id = term()
Types:
Users = [UserId]
UserId = term()
register_agent(UserId, Addr) -> ok | {error, Reason}
register_agent(UserId, Addr, Port) -> ok | {error, Reason}
register_agent(UserId, Addr, Config) -> ok | {error, Reason}
register_agent(UserId, Addr, Port, Config) -> ok | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
Config = [agent_config()]
agent_config() = {Item, Val}
Item = target_name | community | engine_id | timeout | max_message_size | version | sec_model | sec_name | sec_level
Val = term()
Reason = term()
Explicitly instruct the manager to handle this agent, with
UserId
as the responsible user.
Called to instruct the manager that this agent
shall be handled. These functions is used when
the user know's in advance which agents the
manager shall handle.
Note that there is an alternate way to do the same thing:
Add the agent to the manager config files (see agents.conf).
The type of Val
depends on Item
:
target_name = string(),
community = string(),
engine_id = string(),
timeout = integer() | snmp_timer(),
max_message_size = integer(),
version = v1 | v2 | v3,
sec_model = any | v1 | v2c | usm,
sec_name = string()
sec_level = noAuthNoPriv | authNoPriv | authPriv
.
unregister_agent(UserId, Addr) -> ok | {error, Reason}
unregister_agent(UserId, Addr, Port) -> ok | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
agent_info(Addr, Port, Item) -> {ok, Val} | {error, Reason}
Types:
Addr = ip_address()
Port = integer()
Item = atom()
Reason = term()
update_agent_info(UserId, Addr, Port, Item, Val) -> ok | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
Item = atom()
Val = term()
Reason = term()
which_agents() -> Agents
which_agents(UserId) -> Agents
Types:
UserId = term()
Agents = [{Addr,Port}]
Addr = ip_address()
Port = integer()
register_usm_user(EngineID, UserName, Conf) -> ok | {error, Reason}
Types:
EngineID = string()
UserName = string()
Conf = [usm_config()]
usm_config() = {Item, Val}
Item = sec_name | auth | auth_key | priv | priv_key
Val = term()
Reason = term()
Explicitly instruct the manager to handle this USM user. Note that there is an alternate way to do the same thing: Add the usm user to the manager config files (see usm.conf).
The type of Val
depends on Item
:
sec_name = string(),
auth = usmNoAuthProtocol | usmHMACMD5AuthProtocol | usmHMACSHAAuthProtocoltimeout
auth_key = [integer()]
(length 16 if auth = usmHMACMD5AuthProtocol, length 20 if auth = usmHMACSHAAuthProtocol),
priv = usmNoPrivProtocol | usmDESPrivProtocol | usmAesCfb128Protocol
,
priv_key = [integer()]
(length is 16 if priv = usmDESPrivProtocol | usmAesCfb128Protocol).
unregister_usm_user(EngineID, UserName) -> ok | {error, Reason}
Types:
EngineID = string()
UserName = string()
Reason = term()
usm_user_info(EngineID, UserName, Item) -> {ok, Val} | {error, Reason}
Types:
EngineID = string()
UsmName = string()
Item = sec_name | auth | auth_key | priv | priv_key
Reason = term()
update_usm_user_info(EngineID, UserName, Item, Val) -> ok | {error, Reason}
Types:
EngineID = string()
UsmName = string()
Item = sec_name | auth | auth_key | priv | priv_key
Val = term()
Reason = term()
Types:
UsmUsers = [{EngineID,UserName}]
EngineID = string()
UsmName = string()
which_usm_users(EngineID) -> UsmUsers
Types:
UsmUsers = [UserName]
UserName = string()
g(UserId, Addr, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Port, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Port, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Port, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Port, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
g(UserId, Addr, Port, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
ContextName = string()
Oids = [oid()]
Timeout = integer()
ExtraInfo = term()
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, R} | {invalid_sec_info, SecInfo, SnmpInfo} | term()
R = term()
SecInfo = [sec_info()]
sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}
sec_tag() = atom()
ExpectedValue = ReceivedValue = term()
SnmpInfo = term()
Synchronous get-request
.
Remaining
is the remaining time of the given or
default timeout time.
When Reason is {send_failed, ...} it means that the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. R is the actual reason in this case.
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
For SnmpInfo
, see the user callback function
handle_report.
ag(UserId, Addr, Oids) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Port, Oids) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Oids, Expire) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Port, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Port, Oids, Expire) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Port, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
ag(UserId, Addr, Port, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
ContextName = string()
Oids = [oid()]
Expire = integer()
ExtraInfo = term()
ReqId = term()
Reason = term()
Asynchronous get-request
.
The reply, if it arrives, will be delivered to the user
through a call to the snmpm_user callback function
handle_pdu
.
The Expire
time indicates for how long the request is
valid (after which the manager is free to delete it).
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
gn(UserId, Addr, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Port, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Port, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Port, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Port, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gn(UserId, Addr, Port, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
ContextName = string()
Oids = [oid()]
Timeout = integer()
ExtraInfo = term()
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, R} | {invalid_sec_info, SecInfo, SnmpInfo} | term()
R = term()
Synchronous get-next-request
.
Remaining
time of the given or default timeout time.
When Reason is {send_failed, ...} it means that the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. R is the actual reason in this case.
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
agn(UserId, Addr, Oids) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Port, Oids) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Port, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Port, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Port, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agn(UserId, Addr, Port, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
ContextName = string()
Oids = [oid()]
Expire = integer()
ExtraInfo = term()
ReqId = integer()
Reason = term()
Asynchronous get-next-request
.
The reply will be delivered to the user through a call
to the snmpm_user callback function handle_pdu
.
The Expire
time indicates for how long the request is
valid (after which the manager is free to delete it).
s(UserId, Addr, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, Port, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, ContextName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, Port, ContextName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, Port, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, ContextName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, Port, ContextName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
s(UserId, Addr, Port, ContextName, VarsAndVals, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
ContextName = string()
VarsAndVals = [var_and_val()]
var_and_val() = {oid(), value_type(), value()} | {oid(), value()}
value_type() = o ('OBJECT IDENTIFIER') | i ('INTEGER') | u ('Unsigned32') | g ('Unsigned32') | s ('OCTET SRING') | b ('BITS') | ip ('IpAddress') | op ('Opaque') | c32 ('Counter32') | c64 ('Counter64') | tt ('TimeTicks')
value() = term()
Timeout = integer()
ExtraInfo = term()
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, R} | {invalid_sec_info, SecInfo, SnmpInfo} | term()
R = term()
Synchronous set-request
.
Remaining
time of the given or default timeout time.
When Reason is {send_failed, ...} it means that the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. R is the actual reason in this case.
When var_and_val() is {oid(), value()}, the manager makes an educated guess based on the loaded mibs.
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
as(UserId, Addr, VarsAndVals) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, Port, VarsAndVals) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, ContextName, VarsAndVals) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, Port, ContextName, VarsAndVals) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, Port, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, ContextName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, Port, ContextName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}
as(UserId, Addr, Port, ContextName, VarsAndVals, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
VarsAndVals = [var_and_val()]
var_and_val() = {oid(), value_type(), value() | {oid(), value()}
value_type() = o ('OBJECT IDENTIFIER') | i ('INTEGER') | u ('Unsigned32') | g ('Unsigned32') | s ('OCTET SRING') | b ('BITS') | ip ('IpAddress') | op ('Opaque') | c32 ('Counter32') | c64 ('Counter64') | tt ('TimeTicks')
value() = term()
Expire = integer()
ExtraInfo = term()
ReqId = term()
Reason = term()
Asynchronous set-request
.
The reply will be delivered to the user through a call
to the snmpm_user callback function handle_pdu
.
The Expire
time indicates for how long the request is
valid (after which the manager is free to delete it).
When var_and_val() is {oid(), value()}, the manager makes an educated guess based on the loaded mibs.
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
gb(UserId, Addr, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, Port, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, NonRep, MaxRep, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, NonRep, MaxRep, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}
gb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
NonRep = integer()
MaxRep = integer()
ContextName = string()
Oids = [oid()]
Timeout = integer()
ExtraInfo = term()
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, R} | {invalid_sec_info, SecInfo, SnmpInfo} | term()
Synchronous get-bulk-request
(See RFC1905).
Remaining
time of the given or default timeout time.
When Reason is {send_failed, ...} it means that the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. R is the actual reason in this case.
ExtraInfo
is an opaque data structure passed on to
the net-if process. The net-if process included in this
application makes no use of this info, so the only use for it
in such a configuration (when using the built in net-if) would
be tracing.
agb(UserId, Addr, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, Port, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, NonRep, MaxRep, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, NonRep, MaxRep, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, Port, NonRep, MaxRep, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, NonRep, MaxRep, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}
agb(UserId, Addr, Port, NonRep, MaxRep, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}
Types:
UserId = term()
Addr = ip_address()
Port = integer()
NonRep = integer()
MaxRep = integer()
ContextName = string()
Oids = [oid()]
Expire = integer()
ExtraInfo = term()
ReqId = integer()
Reason = term()
Asynchronous get-bulk-request
(See RFC1905).
The reply will be delivered to the user through a call
to the snmpm_user callback function handle_pdu
.
The Expire
time indicates for how long the request is
valid (after which the manager is free to delete it).
cancel_async_request(UserId, ReqId) -> ok | {error, Reason}
Types:
UserId = term()
ReqId = term()
Reason = term()
log_to_txt(LogDir, Mibs)
log_to_txt(LogDir, Mibs, OutFile) -> ok | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName) ->
ok | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile) ->
ok | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start) ->
ok | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop)
-> ok | {error, Reason}
Types:
LogDir = string()
Mibs = [MibName]
MibName = string()
OutFile = string()
LogName = string()
LogFile = string()
Start = Stop = null | datetime() | {local_time,datetime()} |
{universal_time,datetime()}
Reason = disk_log_open_error() | file_open_error() | term()
disk_log_open_error() = {LogName, term()}
file_open_error() = {OutFile, term()}
Converts an Audit Trail Log to a readable text file.
OutFile
defaults to "./snmpm_log.txt".
LogName
defaults to "snmpm_log".
LogFile
defaults to "snmpm.log".
See snmp:log_to_txt
for more info.
change_log_size(NewSize) -> ok | {error, Reason}
Types:
NewSize = {MaxBytes, MaxFiles}
MaxBytes = integer()
MaxFiles = integer()
Reason = term()
Changes the log size of the Audit Trail Log. The application must be configured to use the audit trail log function. Please refer to disk_log(3) in Kernel Reference Manual for a description of how to change the log size.
The change is permanent, as long as the log is not deleted. That means, the log size is remebered across reboots.
load_mib(Mib) -> ok | {error, Reason}
Types:
Mib = MibName
MibName = string()
Reason = term()
Load a Mib
into the manager. The MibName
is the
name of the Mib, including the path to where the compiled mib is
found. For example,
Dir = code:priv_dir(my_app) ++ "/mibs/", snmpm:load_mib(Dir ++ "MY-MIB").
unload_mib(Mib) -> ok | {error, Reason}
Types:
Mib = MibName
MibName = string()
Reason = term()
Unload a Mib
from the manager. The MibName
is the
name of the Mib, including the path to where the compiled mib is
found. For example,
Dir = code:priv_dir(my_app) ++ "/mibs/", snmpm:unload_mib(Dir ++ "MY-MIB").
Types:
Mibs = [{MibName, MibFile}]
MibName = atom()
MibFile = string()
name_to_oid(Name) -> {ok, Oids} | {error, Reason}
Types:
Name = atom()
Oids = [oid()]
Transform a aliasname to it's oid.
Note that an aliasname is only unique within the mib, so when loading several mib's into a manager, there might be several instances of the same aliasname.
oid_to_name(Oid) -> {ok, Name} | {error, Reason}
Types:
Oid = oid()
Name = atom()
Reason = term()
backup(BackupDir) -> ok | {error, Reason}
Types:
BackupDir = string()
Types:
Key = atom()
Value = term()
Returns a list (a dictionary) containing information about the manager. Information includes statistics counters, miscellaneous info about each process (e.g. memory allocation), and so on.
verbosity(Ref, Verbosuity) -> void()
Types:
Ref = server | config | net_if | note_store | all
Verbosity = verbosity()
verbosity() = silence | info | log | debug | trace
Sets verbosity for the designated process. For the lowest
verbosity silence
, nothing is printed. The higher the
verbosity, the more is printed.
format_reason(Reason) -> string()
format_reason(Prefix, Reason) -> string()
Types:
Reason = term()
Prefix = integer() | string()
This utility function is used to create a formatted (pretty printable) string of the error reason received from either:
Reason
returned value if any of the
sync/async get/get-next/set/get-bulk
functions returnes {error, Reason}
Reason
parameter in the
handle_error user callback function.
Prefix
should either be an indention string
(e.g. a list of spaces) or a positive integer (wich will be used
to create the indention string of that length).