# `DalaDev.LogCollector`
[🔗](https://github.com/manhvu/dala_dev/blob/main/lib/dala_dev/log_collector.ex#L1)

Unified log collection from dala Elixir cluster nodes.

Collects logs from:
- BEAM logger (via RPC from remote nodes)
- Android logcat (for Android devices)
- iOS syslog (for iOS simulators/devices)
- Distribution logs (EPMD, net_kernel)

## Examples

    # Stream logs from all connected nodes
    DalaDev.LogCollector.stream_logs(:all_nodes, level: :info)

    # Collect last 100 log lines from a specific node
    DalaDev.LogCollector.collect_logs(:"dala_qa@192.168.1.5", last: 100)

    # Export logs to file
    DalaDev.LogCollector.export_logs("cluster_logs.jsonl", nodes: :all)

# `filter`

```elixir
@type filter() ::
  {:level, Logger.level()}
  | {:module, module()}
  | {:node, node()}
  | {:time_range, {DateTime.t(), DateTime.t()}}
  | {:pattern, String.t() | Regex.t()}
```

# `log_entry`

```elixir
@type log_entry() :: %{
  ts: DateTime.t(),
  node: node(),
  level: Logger.level(),
  message: String.t(),
  metadata: keyword()
}
```

# `node_ref`

```elixir
@type node_ref() :: node() | :all_nodes | DalaDev.Device.t()
```

# `collect_android_logs`

```elixir
@spec collect_android_logs(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}
```

Collect Android logs via adb logcat.

Filters for the app package by default.

# `collect_beam_logs`

```elixir
@spec collect_beam_logs(
  node(),
  keyword()
) :: [log_entry()]
```

Get BEAM VM logs from a remote node via RPC.

Collects from:
- Logger messages in :logger handler
- error_logger (legacy)
- SASL reports (if available)

# `collect_ios_device_logs`

```elixir
@spec collect_ios_device_logs(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}
```

Collect iOS physical device logs via `idevicesyslog` (requires libimobiledevice).

# `collect_ios_sim_logs`

```elixir
@spec collect_ios_sim_logs(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}
```

Collect iOS simulator logs via `xcrun simctl spawn log stream`.

# `collect_logs`

```elixir
@spec collect_logs(
  node_ref(),
  keyword()
) :: {:ok, [log_entry()]} | {:error, term()}
```

Collect logs from a node or all connected nodes.

Options:
- `:last` - number of recent log entries to return
- `:level` - minimum log level (:error, :warning, :info, :debug)
- `:since` - collect logs since this DateTime
- `:format` - :text (default) or :jsonl

# `export_logs`

```elixir
@spec export_logs(
  Path.t(),
  keyword()
) :: :ok | {:error, term()}
```

Export logs to a file.

Format:
- "jsonl" (default) - JSON Lines format, one log per line
- "text" - Human-readable text
- "csv" - CSV format with columns: ts,node,level,message,metadata

# `fetch_local_logs`

```elixir
@spec fetch_local_logs(keyword()) :: [log_entry()]
```

Fetch local logs (called via RPC on remote nodes).

This function runs ON the remote node to collect its local logs.

# `stream_android_logs`

```elixir
@spec stream_android_logs(
  String.t(),
  keyword()
) :: Enumerable.t()
```

Stream Android logs in real-time.

# `stream_logs`

```elixir
@spec stream_logs(
  node_ref(),
  keyword()
) :: Enumerable.t()
```

Stream logs in real-time.

Returns a stream that yields log entries as they arrive.
Call `Stream.run/1` or enumerate to start streaming.

Options:
- `:level` - minimum log level
- `:nodes` - list of nodes or :all_nodes
- `:format` - :text or :jsonl

---

*Consult [api-reference.md](api-reference.md) for complete listing*
