ElixirScope.Utils (elixir_scope v0.0.1)

Utility functions for ElixirScope.

Provides high-performance, reliable utilities for:

  • High-resolution timestamp generation
  • Unique ID generation
  • Data inspection and truncation
  • Performance measurement helpers

Summary

Functions

Formats a byte size into a human-readable string.

Formats a duration in nanoseconds into a human-readable string.

Converts a monotonic timestamp to a human-readable string.

Generates a unique correlation ID for tracing events. Returns a UUID v4 string for compatibility with external systems.

Generates a unique ID for events, calls, and other entities.

Extracts the timestamp component from a generated ID.

Measures execution time of a function in nanoseconds.

Measures memory usage before and after executing a function.

Generates a high-resolution monotonic timestamp in nanoseconds.

Gets current process statistics for performance monitoring.

Safely inspects a term with size limits to prevent memory issues.

Gets system-wide performance statistics.

Estimates the memory footprint of a term in bytes.

Truncates data for safe storage in events.

Truncates a term if it's too large, returning a placeholder.

Validates that a value is a percentage (0.0 to 1.0).

Validates that a PID exists and is alive.

Validates that a value is a positive integer.

Generates a wall clock timestamp in nanoseconds.

Functions

format_bytes(bytes)

Formats a byte size into a human-readable string.

Examples

iex> ElixirScope.Utils.format_bytes(1024)
"1.0 KB"

iex> ElixirScope.Utils.format_bytes(1_500_000)
"1.4 MB"

format_duration(nanoseconds)

Formats a duration in nanoseconds into a human-readable string.

Examples

iex> ElixirScope.Utils.format_duration(1_500_000)
"1.5 ms"

iex> ElixirScope.Utils.format_duration(2_000_000_000)
"2.0 s"

format_timestamp(timestamp_ns)

Converts a monotonic timestamp to a human-readable string.

Examples

iex> ElixirScope.Utils.format_timestamp(315708474309417000)
"2024-01-01 12:30:45.123456789"

generate_correlation_id()

Generates a unique correlation ID for tracing events. Returns a UUID v4 string for compatibility with external systems.

generate_id()

Generates a unique ID for events, calls, and other entities.

The ID is designed to be:

  • Globally unique across nodes and time
  • Sortable (roughly by creation time)
  • Compact for storage efficiency
  • Fast to generate

Examples

iex> id1 = ElixirScope.Utils.generate_id()
iex> id2 = ElixirScope.Utils.generate_id()
iex> id1 != id2
true

id_to_timestamp(id)

Extracts the timestamp component from a generated ID.

Examples

iex> id = ElixirScope.Utils.generate_id()
iex> timestamp = ElixirScope.Utils.id_to_timestamp(id)
iex> is_integer(timestamp)
true

measure(fun)

Measures execution time of a function in nanoseconds.

Examples

iex> {result, duration} = ElixirScope.Utils.measure(fn -> :timer.sleep(10); :ok end)
iex> result
:ok
iex> duration > 10_000_000  # At least 10ms in nanoseconds
true

measure_memory(fun)

Measures memory usage before and after executing a function.

Returns {result, {memory_before, memory_after, memory_diff}}.

Examples

iex> {result, {before, after, diff}} = ElixirScope.Utils.measure_memory(fn -> 
...>   Enum.to_list(1..1000)
...> end)
iex> is_list(result)
true
iex> diff > 0
true

monotonic_timestamp()

Generates a high-resolution monotonic timestamp in nanoseconds.

This timestamp is guaranteed to be monotonically increasing and is suitable for ordering events and measuring durations. It's not affected by system clock adjustments.

Examples

iex> ElixirScope.Utils.monotonic_timestamp()
315708474309417000

process_stats(pid \\ self())

Gets current process statistics for performance monitoring.

Examples

iex> stats = ElixirScope.Utils.process_stats()
iex> Map.has_key?(stats, :memory)
true
iex> Map.has_key?(stats, :reductions)
true

safe_inspect(term, opts \\ [])

Safely inspects a term with size limits to prevent memory issues.

Examples

iex> ElixirScope.Utils.safe_inspect(%{key: "value"})
"%{key: "value"}"

iex> large_map = for i <- 1..1000, into: %{}, do: {i, i}
iex> result = ElixirScope.Utils.safe_inspect(large_map)
iex> String.contains?(result, "...")
true

system_stats()

Gets system-wide performance statistics.

Examples

iex> stats = ElixirScope.Utils.system_stats()
iex> Map.has_key?(stats, :process_count)
true
iex> Map.has_key?(stats, :total_memory)
true

term_size(term)

Estimates the memory footprint of a term in bytes.

Examples

iex> ElixirScope.Utils.term_size("hello")
15

truncate_data(term, max_size \\ 1000)

Truncates data for safe storage in events.

This is an alias for truncate_if_large/2 with a smaller default size suitable for event data.

Examples

iex> ElixirScope.Utils.truncate_data("small")
"small"

iex> large_data = String.duplicate("x", 2000)
iex> ElixirScope.Utils.truncate_data(large_data)
{:truncated, 2000, "binary data"}

truncate_if_large(term, max_size \\ 5000)

Truncates a term if it's too large, returning a placeholder.

Examples

iex> ElixirScope.Utils.truncate_if_large("small")
"small"

iex> large_binary = String.duplicate("x", 10000)
iex> ElixirScope.Utils.truncate_if_large(large_binary, 1000)
{:truncated, 10000, "binary data"}

valid_percentage?(value)

Validates that a value is a percentage (0.0 to 1.0).

Examples

iex> ElixirScope.Utils.valid_percentage?(0.5)
true

iex> ElixirScope.Utils.valid_percentage?(1.5)
false

valid_pid?(pid)

Validates that a PID exists and is alive.

Examples

iex> ElixirScope.Utils.valid_pid?(self())
true

iex> dead_pid = spawn(fn -> nil end)
iex> Process.sleep(10)
iex> ElixirScope.Utils.valid_pid?(dead_pid)
false

valid_positive_integer?(value)

Validates that a value is a positive integer.

Examples

iex> ElixirScope.Utils.valid_positive_integer?(42)
true

iex> ElixirScope.Utils.valid_positive_integer?(-1)
false

wall_timestamp()

Generates a wall clock timestamp in nanoseconds.

This timestamp represents the actual time and can be converted to human-readable dates. Use for correlation with external systems.

Examples

iex> ElixirScope.Utils.wall_timestamp()
1609459200000000000