Skip to content

Commit

Permalink
Merge pull request #1770 from omgnetwork/add-metadata-to-dd-traces-2
Browse files Browse the repository at this point in the history
feat: add new metadata to Datadog traces (attempt 2)
  • Loading branch information
Michael Captain authored Nov 20, 2020
2 parents 4f5756b + 1f73eb5 commit 0a7a6e8
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 15 deletions.
3 changes: 2 additions & 1 deletion apps/omg_watcher_rpc/lib/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ defmodule OMG.WatcherRPC.Application do
_ =
SpandexPhoenix.Telemetry.install(
endpoint_telemetry_prefix: [:watcher_rpc, :endpoint],
tracer: OMG.WatcherRPC.Tracer
tracer: OMG.WatcherRPC.Tracer,
customize_metadata: &OMG.WatcherRPC.Tracer.add_trace_metadata/1
)

children = [
Expand Down
30 changes: 30 additions & 0 deletions apps/omg_watcher_rpc/lib/configuration.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.Configuration do
@moduledoc """
Provides access to applications configuration
"""
@app :omg_watcher_rpc

@spec version() :: String.t()
def version() do
OMG.Utils.HttpRPC.Response.version(@app)
end

@spec service_name() :: atom()
def service_name() do
Application.get_env(@app, :api_mode)
end
end
22 changes: 22 additions & 0 deletions apps/omg_watcher_rpc/lib/tracer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,26 @@ defmodule OMG.WatcherRPC.Tracer do
"""

use Spandex.Tracer, otp_app: :omg_watcher_rpc
alias OMG.WatcherRPC.Configuration

def add_trace_metadata(%{assigns: %{error_type: error_type, error_msg: error_msg}} = conn) do
service_name = Configuration.service_name()
version = Configuration.version()

conn
|> SpandexPhoenix.default_metadata()
|> Keyword.put(:service, service_name)
|> Keyword.put(:error, [{:error, true}])
|> Keyword.put(:tags, [{:version, version}, {:"error.type", error_type}, {:"error.msg", error_msg}])
end

def add_trace_metadata(conn) do
service_name = Configuration.service_name()
version = Configuration.version()

conn
|> SpandexPhoenix.default_metadata()
|> Keyword.put(:service, service_name)
|> Keyword.put(:tags, [{:version, version}])
end
end
17 changes: 3 additions & 14 deletions apps/omg_watcher_rpc/lib/web/response.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,15 @@ defmodule OMG.WatcherRPC.Web.Response do
For the generic response, see `OMG.Utils.HttpRPC.Response`.
"""

@app :omg_watcher_rpc
alias OMG.WatcherRPC.Configuration

@doc """
Adds "version" and "service_name" to the response map.
"""
@spec add_app_infos(map()) :: %{version: String.t(), service_name: String.t()}
def add_app_infos(response) do
response
|> Map.put(:version, version())
|> Map.put(:service_name, service_name())
end

defp version() do
OMG.Utils.HttpRPC.Response.version(@app)
end

defp service_name() do
case Application.get_env(@app, :api_mode) do
:watcher -> "watcher"
:watcher_info -> "watcher_info"
end
|> Map.put(:version, Configuration.version())
|> Map.put(:service_name, "#{Configuration.service_name()}")
end
end
107 changes: 107 additions & 0 deletions apps/omg_watcher_rpc/test/omg_watcher_rpc/tracer_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.TracerTest do
@app :omg_watcher_rpc

use ExUnit.Case
import Plug.Conn
alias OMG.WatcherRPC.Configuration
alias OMG.WatcherRPC.Tracer

setup do
original_mode = Application.get_env(:omg_watcher_rpc, :api_mode)
_ = on_exit(fn -> Application.put_env(:omg_watcher_rpc, :api_mode, original_mode) end)

:ok
end

test "api responses without errors get traced with metadata" do
:ok = Application.put_env(@app, :api_mode, :watcher)
version = Configuration.version()

resp_body = """
{
"data": [],
"service_name": "watcher",
"success": true,
"version": "#{version}"
}
"""

conn =
:get
|> Phoenix.ConnTest.build_conn("/alerts.get")
|> Plug.Conn.resp(200, resp_body)

trace_metadata = Tracer.add_trace_metadata(conn)

expected =
Keyword.new([
{:tags, [version: version]},
{:service, :watcher},
{:http, [method: "GET", query_string: "", status_code: 200, url: "/alerts.get", user_agent: nil]},
{:resource, "GET /alerts.get"},
{:type, :web}
])

assert trace_metadata == expected
end

test "if api responses with errors get traced with metadata" do
:ok = Application.put_env(@app, :api_mode, :watcher_info)
version = Configuration.version()

resp_body = """
{
"data": {
"code": "operation:not_found",
"description": "Operation cannot be found. Check request URL.",
"object": "error"
},
"service_name": "watcher_info",
"success": false,
"version": "#{version}"
}
"""

conn =
:post
|> Phoenix.ConnTest.build_conn("/")
|> Plug.Conn.resp(200, resp_body)
|> assign(:error_type, "operation:not_found")
|> assign(:error_msg, "Operation cannot be found. Check request URL.")

trace_metadata = Tracer.add_trace_metadata(conn)

expected =
Keyword.new([
{
:tags,
[
{:version, version},
{:"error.type", "operation:not_found"},
{:"error.msg", "Operation cannot be found. Check request URL."}
]
},
{:error, [error: true]},
{:service, :watcher_info},
{:http, [method: "POST", query_string: "", status_code: 200, url: "/", user_agent: nil]},
{:resource, "POST /"},
{:type, :web}
])

assert trace_metadata == expected
end
end

0 comments on commit 0a7a6e8

Please sign in to comment.