Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add telemetry events #204

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
- Remove calls to deprecated `Logger.warn/2`
- Correct misspell of 'Empd' -> 'Epmd' in `Cluster.Strategy.LocalEpmd` moduledoc

## 3.4.0

### Added

- Telemetry events added for tracking node connects and disconnects

### 3.3.0

### Changed
Expand Down
46 changes: 46 additions & 0 deletions lib/strategy/strategy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,36 @@ defmodule Cluster.Strategy do
fargs = connect_args ++ [n]
ensure_exported!(connect_mod, connect_fun, length(fargs))

start = System.monotonic_time()

case apply(connect_mod, connect_fun, fargs) do
true ->
:telemetry.execute(
[:libcluster, :connect_node, :ok],
%{duration: System.monotonic_time() - start},
%{node: n, topology: topology}
)

Cluster.Logger.info(topology, "connected to #{inspect(n)}")
acc

false ->
:telemetry.execute(
[:libcluster, :connect_node, :error],
%{},
%{node: n, topology: topology, reason: :unreachable}
)

Cluster.Logger.warn(topology, "unable to connect to #{inspect(n)}")
[{n, false} | acc]

:ignored ->
:telemetry.execute(
[:libcluster, :connect_node, :error],
%{},
%{node: n, topology: topology, reason: :not_part_of_network}
)

Cluster.Logger.warn(
topology,
"unable to connect to #{inspect(n)}: not part of network"
Expand Down Expand Up @@ -100,12 +120,26 @@ defmodule Cluster.Strategy do
fargs = disconnect_args ++ [n]
ensure_exported!(disconnect_mod, disconnect_fun, length(fargs))

start = System.monotonic_time()

case apply(disconnect_mod, disconnect_fun, fargs) do
true ->
:telemetry.execute(
[:libcluster, :disconnect_node, :ok],
%{duration: System.monotonic_time() - start},
%{node: n, topology: topology}
)

Cluster.Logger.info(topology, "disconnected from #{inspect(n)}")
acc

false ->
:telemetry.execute(
[:libcluster, :disconnect_node, :error],
%{},
%{node: n, topology: topology, reason: :already_disconnected}
)

Cluster.Logger.warn(
topology,
"disconnect from #{inspect(n)} failed because we're already disconnected"
Expand All @@ -114,6 +148,12 @@ defmodule Cluster.Strategy do
acc

:ignored ->
:telemetry.execute(
[:libcluster, :disconnect_node, :error],
%{},
%{node: n, topology: topology, reason: :not_part_of_network}
)

Cluster.Logger.warn(
topology,
"disconnect from #{inspect(n)} failed because it is not part of the network"
Expand All @@ -122,6 +162,12 @@ defmodule Cluster.Strategy do
acc

reason ->
:telemetry.execute(
[:libcluster, :disconnect_node, :error],
%{},
%{node: n, topology: topology, reason: inspect(reason)}
)

Cluster.Logger.warn(
topology,
"disconnect from #{inspect(n)} failed with: #{inspect(reason)}"
Expand Down
5 changes: 3 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Cluster.Mixfile do
use Mix.Project

@version "3.3.3"
@version "3.4.0"
@source_url "https://github.com/bitwalker/libcluster"

def project do
Expand Down Expand Up @@ -40,7 +40,8 @@ defmodule Cluster.Mixfile do
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
{:dialyxir, "~> 1.0", only: :dev, runtime: false},
{:exvcr, "~> 0.11", only: :test, runtime: false},
{:jason, "~> 1.1"}
{:jason, "~> 1.1"},
{:telemetry, "~> 1.3"}
]
end

Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
}
31 changes: 31 additions & 0 deletions test/strategy_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Cluster.StrategyTest do

alias Cluster.Strategy
alias Cluster.Nodes
alias Cluster.Telemetry

require Cluster.Nodes

Expand All @@ -24,36 +25,54 @@ defmodule Cluster.StrategyTest do
connect = {Nodes, :connect, [self()]}
list_nodes = {Nodes, :list_nodes, [[Node.self()]]}

Telemetry.setup_telemetry([:libcluster, :connect_node, :ok])

assert capture_log(fn ->
assert :ok =
Strategy.connect_nodes(__MODULE__, connect, list_nodes, [:"foo@some.host"])
end) =~ "connected to :\"foo@some.host\""

assert_receive {:connect, :"foo@some.host"}

assert_receive {:telemetry_event,
{[:libcluster, :connect_node, :ok], %{duration: _},
%{node: :"foo@some.host", topology: _}, _}}
end

test "handles connect failure" do
connect = {Nodes, :connect, [self(), false]}
list_nodes = {Nodes, :list_nodes, [[Node.self()]]}

Telemetry.setup_telemetry([:libcluster, :connect_node, :error])

assert capture_log(fn ->
assert {:error, ["foo@some.host": false]} =
Strategy.connect_nodes(__MODULE__, connect, list_nodes, [:"foo@some.host"])
end) =~ "unable to connect to :\"foo@some.host\""

assert_receive {:connect, :"foo@some.host"}

assert_receive {:telemetry_event,
{[:libcluster, :connect_node, :error], %{},
%{node: :"foo@some.host", topology: _, reason: :unreachable}, _}}
end

test "handles connect ignore" do
connect = {Nodes, :connect, [self(), :ignored]}
list_nodes = {Nodes, :list_nodes, [[Node.self()]]}

Telemetry.setup_telemetry([:libcluster, :connect_node, :error])

assert capture_log(fn ->
assert {:error, ["foo@some.host": :ignored]} =
Strategy.connect_nodes(__MODULE__, connect, list_nodes, [:"foo@some.host"])
end) =~ "unable to connect to :\"foo@some.host\""

assert_receive {:connect, :"foo@some.host"}

assert_receive {:telemetry_event,
{[:libcluster, :connect_node, :error], %{},
%{node: :"foo@some.host", topology: _, reason: :not_part_of_network,}, _}}
end
end

Expand All @@ -71,6 +90,8 @@ defmodule Cluster.StrategyTest do
disconnect = {Nodes, :disconnect, [self()]}
list_nodes = {Nodes, :list_nodes, [[:"foo@some.host"]]}

Telemetry.setup_telemetry([:libcluster, :disconnect_node, :ok])

assert capture_log(fn ->
assert :ok =
Strategy.disconnect_nodes(__MODULE__, disconnect, list_nodes, [
Expand All @@ -79,12 +100,18 @@ defmodule Cluster.StrategyTest do
end) =~ "disconnected from :\"foo@some.host\""

assert_receive {:disconnect, :"foo@some.host"}

assert_receive {:telemetry_event,
{[:libcluster, :disconnect_node, :ok], %{duration: _},
%{node: :"foo@some.host", topology: _}, _}}
end

test "handles disconnect error" do
disconnect = {Nodes, :disconnect, [self(), :failed]}
list_nodes = {Nodes, :list_nodes, [[:"foo@some.host"]]}

Telemetry.setup_telemetry([:libcluster, :disconnect_node, :error])

assert capture_log(fn ->
assert {:error, ["foo@some.host": :failed]} =
Strategy.disconnect_nodes(__MODULE__, disconnect, list_nodes, [
Expand All @@ -94,6 +121,10 @@ defmodule Cluster.StrategyTest do
"disconnect from :\"foo@some.host\" failed with: :failed"

assert_receive {:disconnect, :"foo@some.host"}

assert_receive {:telemetry_event,
{[:libcluster, :disconnect_node, :error], %{},
%{node: :"foo@some.host", topology: _, reason: ":failed"}, _}}
end
end
end
26 changes: 26 additions & 0 deletions test/support/telemetry.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule Cluster.Telemetry do
@moduledoc false

use ExUnit.Case

def setup_telemetry(event) do
telemetry_handle_id = "test-telemetry-handler-#{inspect(self())}"

:ok = :telemetry.attach_many(
telemetry_handle_id,
[
event,
],
&send_to_pid/4,
nil
)

:ok = on_exit(fn -> :telemetry.detach(telemetry_handle_id) end)
end

defp send_to_pid(event, measurements, metadata, config) do
pid = config[:pid] || self()

send(pid, {:telemetry_event, {event, measurements, metadata, config}})
end
end
Loading