Skip to content

Instantly share code, notes, and snippets.

@slashdotdash
Last active July 13, 2020 08:42
Show Gist options
  • Save slashdotdash/6c0f1dbdf40a2628fa4d8fc13c388762 to your computer and use it in GitHub Desktop.
Save slashdotdash/6c0f1dbdf40a2628fa4d8fc13c388762 to your computer and use it in GitHub Desktop.
A Commanded middleware to instrument the command dispatch pipeline with `:telemetry` events.
defmodule Commanded.Middleware.Telemetry do
@moduledoc """
A Commanded middleware to instrument the command dispatch pipeline with
`:telemetry` events.
It produces the following three events:
- `[:commanded, :command, :dispatch, :start]`
- `[:commanded, :command, :dispatch, :success]`
- `[:commanded, :command, :dispatch, :failure]`
"""
@behaviour Commanded.Middleware
alias Commanded.Middleware.Pipeline
import Pipeline
def before_dispatch(%Pipeline{} = pipeline) do
%Pipeline{command: command, metadata: metadata} = pipeline
:telemetry.execute(
[:commanded, :command, :dispatch, :start],
%{time: System.system_time()},
%{command: command, metadata: metadata}
)
assign(pipeline, :start_time, monotonic_time())
end
def after_dispatch(%Pipeline{} = pipeline) do
%Pipeline{command: command, metadata: metadata} = pipeline
:telemetry.execute(
[:commanded, :command, :dispatch, :success],
%{duration: duration(pipeline)},
%{command: command, metadata: metadata}
)
pipeline
end
def after_failure(%Pipeline{} = pipeline) do
%Pipeline{command: command, metadata: metadata} = pipeline
:telemetry.execute(
[:commanded, :command, :dispatch, :failure],
%{duration: duration(pipeline)},
%{command: command, metadata: metadata}
)
pipeline
end
# Calculate the duration, in microseconds, between start time and now.
defp duration(%Pipeline{assigns: %{start_time: start_time}}) do
monotonic_time() - start_time
end
defp duration(%Pipeline{}), do: nil
defp monotonic_time, do: System.monotonic_time(:microsecond)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment