SnmpKit.SnmpLib.Utils (snmpkit v0.6.3)

Common utilities for SNMP operations including pretty printing, data formatting, timing utilities, and validation functions.

This module provides helpful utilities for debugging, logging, monitoring, and general SNMP data manipulation that are commonly needed across SNMP applications.

Pretty Printing

Format SNMP data structures for human-readable display in logs, CLI tools, and debugging output.

Data Formatting

Convert between different representations of SNMP data, format numeric values, and handle common data transformations.

Timing Utilities

Measure and format timing information for SNMP operations, useful for performance monitoring and debugging.

Validation

Common validation functions for SNMP-related data.

Usage Examples

Pretty Printing

# Format PDU for logging
pdu = %{type: :get_request, request_id: 123, varbinds: [...]}
Logger.info(SnmpKit.SnmpLib.Utils.pretty_print_pdu(pdu))

# Format individual values
value = {:counter32, 12345}
IO.puts(SnmpKit.SnmpLib.Utils.pretty_print_value(value))

Data Formatting

# Format large numbers with separators
SnmpKit.SnmpLib.Utils.format_bytes(1048576)
# => "1.0 MB"

# Format hex strings for MAC addresses
SnmpKit.SnmpLib.Utils.format_hex(<<0x00, 0x1B, 0x21, 0x3C, 0x92, 0xEB>>)
# => "00:1B:21:3C:92:EB"

Timing

# Time an operation
{result, time_us} = SnmpKit.SnmpLib.Utils.measure_request_time(fn ->
  SnmpKit.SnmpLib.PDU.encode_message(pdu)
end)

formatted_time = SnmpKit.SnmpLib.Utils.format_response_time(time_us)

Summary

Functions

Formats byte counts in human-readable units.

Formats binary data as hexadecimal string.

Formats large numbers with thousand separators.

Formats rates with units.

Formats response time in human-readable units.

Measures the execution time of a function in microseconds.

Parses SNMP target specifications into standardized format.

Pretty prints an OID for display.

Pretty prints an SNMP PDU for human-readable display.

Pretty prints an SNMP value for display.

Pretty prints a list of varbinds for display.

Sanitizes a community string for safe logging.

Truncates a string to maximum length with ellipsis.

Validates an SNMP community string.

Validates an SNMP version number.

Types

oid()

@type oid() :: [non_neg_integer()]

pdu()

@type pdu() :: map()

snmp_value()

@type snmp_value() :: any()

varbind()

@type varbind() :: {oid(), snmp_value()}

varbinds()

@type varbinds() :: [varbind()]

Functions

format_bytes(bytes)

@spec format_bytes(non_neg_integer()) :: String.t()

Formats byte counts in human-readable units.

Examples

iex> SnmpKit.SnmpLib.Utils.format_bytes(1024)
"1.0 KB"

iex> SnmpKit.SnmpLib.Utils.format_bytes(1048576)
"1.0 MB"

iex> SnmpKit.SnmpLib.Utils.format_bytes(512)
"512 B"

format_hex(data, separator \\ ":")

@spec format_hex(binary(), String.t()) :: String.t()

Formats binary data as hexadecimal string.

Parameters

  • data: Binary data to format
  • separator: String to use between hex bytes (default: ":")

Examples

iex> SnmpKit.SnmpLib.Utils.format_hex(<<0x00, 0x1B, 0x21>>)
"00:1B:21"

iex> SnmpKit.SnmpLib.Utils.format_hex(<<0xDE, 0xAD, 0xBE, 0xEF>>, " ")
"DE AD BE EF"

format_number(number)

@spec format_number(integer()) :: String.t()

Formats large numbers with thousand separators.

Examples

iex> SnmpKit.SnmpLib.Utils.format_number(1234567)
"1,234,567"

iex> SnmpKit.SnmpLib.Utils.format_number(42)
"42"

format_rate(value, unit)

@spec format_rate(number(), String.t()) :: String.t()

Formats rates with units.

Examples

iex> SnmpKit.SnmpLib.Utils.format_rate(1500, "bps")
"1.5 Kbps"

iex> SnmpKit.SnmpLib.Utils.format_rate(45, "pps")
"45 pps"

format_response_time(microseconds)

@spec format_response_time(non_neg_integer()) :: String.t()

Formats response time in human-readable units.

Parameters

  • microseconds: Time in microseconds

Examples

iex> SnmpKit.SnmpLib.Utils.format_response_time(1500)
"1.50ms"

iex> SnmpKit.SnmpLib.Utils.format_response_time(2_500_000)
"2.50s"

iex> SnmpKit.SnmpLib.Utils.format_response_time(500)
"500μs"

measure_request_time(fun)

@spec measure_request_time(function()) :: {any(), non_neg_integer()}

Measures the execution time of a function in microseconds.

Parameters

  • fun: Function to execute and time

Returns

Tuple of {result, time_microseconds} where result is the function's return value and time_microseconds is the execution time.

Examples

iex> {result, time} = SnmpKit.SnmpLib.Utils.measure_request_time(fn -> :timer.sleep(100); :ok end)
iex> result
:ok
iex> time > 100_000
true

parse_target(target)

@spec parse_target(String.t() | tuple() | map()) ::
  {:ok, %{host: :inet.ip_address() | String.t(), port: pos_integer()}}
  | {:error, any()}

Parses SNMP target specifications into standardized format.

Accepts various input formats and returns a consistent target map with host and port. IP addresses are resolved to tuples when possible, hostnames remain as strings. Default port is 161 when not specified.

Parameters

  • target: Target specification in various formats

Accepted Input Formats

  • "192.168.1.1:161" - IP with port
  • "192.168.1.1" - IP without port (uses default 161)
  • "device.local:162" - hostname with port
  • "device.local" - hostname without port (uses default 161)
  • {192, 168, 1, 1} - IP tuple (uses default port 161)
  • %{host: "192.168.1.1", port: 161} - already parsed map

Returns

  • {:ok, %{host: host, port: port}} - Successfully parsed target
  • {:error, reason} - Parse error with reason

Examples

iex> SnmpKit.SnmpLib.Utils.parse_target("192.168.1.1:161")
{:ok, %{host: {192, 168, 1, 1}, port: 161}}

iex> SnmpKit.SnmpLib.Utils.parse_target("192.168.1.1")
{:ok, %{host: {192, 168, 1, 1}, port: 161}}

iex> SnmpKit.SnmpLib.Utils.parse_target("device.local:162")
{:ok, %{host: "device.local", port: 162}}

iex> SnmpKit.SnmpLib.Utils.parse_target("device.local")
{:ok, %{host: "device.local", port: 161}}

iex> SnmpKit.SnmpLib.Utils.parse_target({192, 168, 1, 1})
{:ok, %{host: {192, 168, 1, 1}, port: 161}}

iex> SnmpKit.SnmpLib.Utils.parse_target(%{host: "192.168.1.1", port: 161})
{:ok, %{host: {192, 168, 1, 1}, port: 161}}

iex> SnmpKit.SnmpLib.Utils.parse_target("invalid:99999")
{:error, {:invalid_port, "99999"}}

pretty_print_oid(oid)

@spec pretty_print_oid(oid() | String.t()) :: String.t()

Pretty prints an OID for display.

Examples

iex> SnmpKit.SnmpLib.Utils.pretty_print_oid([1,3,6,1,2,1,1,1,0])
"1.3.6.1.2.1.1.1.0"

iex> SnmpKit.SnmpLib.Utils.pretty_print_oid("1.3.6.1.2.1.1.1.0")
"1.3.6.1.2.1.1.1.0"

pretty_print_pdu(pdu)

@spec pretty_print_pdu(pdu()) :: String.t()

Pretty prints an SNMP PDU for human-readable display.

Formats the PDU structure with proper indentation and readable field names, suitable for logging, debugging, or CLI display.

Parameters

  • pdu: SNMP PDU map containing type, request_id, error_status, etc.

Returns

Formatted string representation of the PDU.

Examples

iex> pdu = %{type: :get_request, request_id: 123, varbinds: [{[1,3,6,1,2,1,1,1,0], :null}]}
iex> result = SnmpKit.SnmpLib.Utils.pretty_print_pdu(pdu)
iex> String.contains?(result, "GET Request")
true

pretty_print_value(value)

@spec pretty_print_value(snmp_value()) :: String.t()

Pretty prints an SNMP value for display.

Formats SNMP values with appropriate type information and human-readable representations.

Examples

iex> SnmpKit.SnmpLib.Utils.pretty_print_value({:counter32, 12345})
"Counter32: 12,345"

iex> SnmpKit.SnmpLib.Utils.pretty_print_value({:octet_string, "Hello"})
"OCTET STRING: \"Hello\""

iex> SnmpKit.SnmpLib.Utils.pretty_print_value(:null)
"NULL"

pretty_print_varbinds(varbinds)

@spec pretty_print_varbinds(varbinds()) :: String.t()

Pretty prints a list of varbinds for display.

Examples

iex> varbinds = [{[1,3,6,1,2,1,1,1,0], "Linux server"}]
iex> result = SnmpKit.SnmpLib.Utils.pretty_print_varbinds(varbinds)
iex> String.contains?(result, "1.3.6.1.2.1.1.1.0")
true

sanitize_community(community)

@spec sanitize_community(String.t()) :: String.t()

Sanitizes a community string for safe logging.

Replaces community strings with asterisks to prevent credential leakage in logs while preserving length information.

Examples

iex> SnmpKit.SnmpLib.Utils.sanitize_community("secret123")
"*********"

iex> SnmpKit.SnmpLib.Utils.sanitize_community("")
"<empty>"

truncate_string(string, max_length)

@spec truncate_string(String.t(), pos_integer()) :: String.t()

Truncates a string to maximum length with ellipsis.

Examples

iex> SnmpKit.SnmpLib.Utils.truncate_string("Hello, World!", 10)
"Hello, ..."

iex> SnmpKit.SnmpLib.Utils.truncate_string("Short", 10)
"Short"

valid_community_string?(community)

@spec valid_community_string?(any()) :: boolean()

Validates an SNMP community string.

Community strings should be non-empty and contain only printable characters.

Examples

iex> SnmpKit.SnmpLib.Utils.valid_community_string?("public")
true

iex> SnmpKit.SnmpLib.Utils.valid_community_string?("")
false

valid_snmp_version?(version)

@spec valid_snmp_version?(any()) :: boolean()

Validates an SNMP version number.

Examples

iex> SnmpKit.SnmpLib.Utils.valid_snmp_version?(1)
true

iex> SnmpKit.SnmpLib.Utils.valid_snmp_version?(5)
false