Created
June 27, 2018 00:04
-
-
Save cjbell/3b6d80187db0032a78e8b1a1d17f095f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Monitoring.Decorator do | |
@moduledoc """ | |
`Decorator` functions for doing monitoring. | |
""" | |
use Decorator.Define, [measure: 0, measure: 1] | |
alias Monitoring.Statix | |
require Logger | |
@doc """ | |
Decorates a method with `Statix.measure`. | |
The name is inferred from the module name and func name. Eg: | |
`Core.Accounts.get_account` = `core.accounts.get_account` | |
""" | |
def measure(body, %{module: mod, name: func} = context) do | |
quote do | |
name = Monitoring.Decorator.context_to_name(unquote(mod), unquote(func)) | |
context = unquote(extract_context(context)) | |
name | |
|> Statix.measure(fn -> unquote(body) end) | |
|> Monitoring.Decorator.log_response(name, context) | |
end | |
end | |
@doc """ | |
Decorates a method with `Statix.measure`. Name is a required arg. | |
""" | |
def measure(name, body, context) do | |
quote do | |
name = unquote(name) | |
context = unquote(extract_context(context)) | |
name | |
|> Statix.measure(fn -> unquote(body) end) | |
|> Monitoring.Decorator.log_response(name, context) | |
end | |
end | |
def context_to_name(mod, func) do | |
mod_name(mod) <> "." <> Atom.to_string(func) | |
end | |
def log_response({:ok, _} = result, name, context) do | |
name <> ".succeeded" |> log_and_increment(context) | |
result | |
end | |
def log_response({:error, _} = result, name, context) do | |
name <> ".failed" |> log_and_increment(context) | |
result | |
end | |
def log_response(result, name, context) do | |
name <> ".calls" |> log_and_increment(context) | |
result | |
end | |
def log_and_increment(name, metadata \\ %{}) do | |
event_data = %{String.to_atom(name) => metadata} | |
Logger.debug(fn -> "[Service] " <> name end, event: event_data) | |
name |> Statix.increment() | |
end | |
def mod_name(mod) when is_atom(mod), do: Atom.to_string(mod) |> mod_name() | |
def mod_name("Elixir." <> mod), do: mod |> mod_name() | |
def mod_name(mod), do: mod |> String.downcase() | |
def extract_context(%{module: mod, name: name, arity: arity}) do | |
quote do | |
%{mod: unquote(mod), name: unquote(name), arity: unquote(arity)} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage is like: