Search documentation of snmpkit

# SnmpKit.SnmpLib.Utils (snmpkit v1.3.17)

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

## Types

oid()
pdu()
snmp_value()
varbind()
varbinds()

## Functions

format_bytes(bytes)

Formats byte counts in human-readable units.

format_hex(data, separator \\ ":")

Formats binary data as hexadecimal string.

format_number(number)

Formats large numbers with thousand separators.

format_rate(value, unit)

Formats rates with units.

format_response_time(microseconds)

Formats response time in human-readable units.

measure_request_time(fun)

Measures the execution time of a function in microseconds.

parse_target(target)

Parses SNMP target specifications into standardized format.

pretty_print_oid(oid)

Pretty prints an OID for display.

pretty_print_pdu(pdu)

Pretty prints an SNMP PDU for human-readable display.

pretty_print_value(value)

Pretty prints an SNMP value for display.

pretty_print_varbinds(varbinds)

Pretty prints a list of varbinds for display.

sanitize_community(community)

Sanitizes a community string for safe logging.

truncate_string(string, max_length)

Truncates a string to maximum length with ellipsis.

valid_community_string?(community)

Validates an SNMP community string.

valid_snmp_version?(version)

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