changed
CHANGELOG.md
|
@@ -1,5 1,12 @@
|
1
1
|
## CHANGELOG
|
2
2
|
|
3
|
### `v1.25.0`
|
4
|
|
5
|
Features
|
6
|
* Support for any `Ecto` adapter, including SQLite and MSSQL. [#337](https://github.com/newrelic/elixir_agent/pull/337) Thanks @marocchino!
|
7
|
|
8
|
------
|
9
|
|
3
10
|
### `v1.24.5`
|
4
11
|
|
5
12
|
Fixes
|
changed
VERSION
|
@@ -1 1 @@
|
1
|
- 1.24.5
|
1
|
1.25.0
|
changed
hex_metadata.config
|
@@ -158,4 158,4 @@
|
158
158
|
{<<"optional">>,true},
|
159
159
|
{<<"repository">>,<<"hexpm">>},
|
160
160
|
{<<"requirement">>,<<">= 0.11.0">>}]]}.
|
161
|
- {<<"version">>,<<"1.24.5">>}.
|
161
|
{<<"version">>,<<"1.25.0">>}.
|
changed
lib/new_relic/telemetry/ecto/handler.ex
|
@@ -1,6 1,8 @@
|
1
1
|
defmodule NewRelic.Telemetry.Ecto.Handler do
|
2
2
|
@moduledoc false
|
3
3
|
|
4
|
alias NewRelic.Telemetry.Ecto.Metadata
|
5
|
|
4
6
|
def handle_event(
|
5
7
|
_event,
|
6
8
|
%{total_time: total_time} = measurements,
|
|
@@ -27,7 29,7 @@ defmodule NewRelic.Telemetry.Ecto.Handler do
|
27
29
|
id = {:ecto_sql_query, make_ref()}
|
28
30
|
parent_id = Process.get(:nr_current_span) || :root
|
29
31
|
|
30
|
- with {datastore, table, operation} <- NewRelic.Telemetry.Ecto.Metadata.parse(metadata) do
|
32
|
with {datastore, {table, operation}} <- Metadata.parse(metadata) do
|
31
33
|
metric_name = "Datastore/statement/#{datastore}/#{table}/#{operation}"
|
32
34
|
secondary_name = "#{inspect(repo)} #{hostname}:#{port}/#{database}"
|
changed
lib/new_relic/telemetry/ecto/metadata.ex
|
@@ -1,64 1,68 @@
|
1
1
|
defmodule NewRelic.Telemetry.Ecto.Metadata do
|
2
2
|
@moduledoc false
|
3
3
|
|
4
|
- @postgrex_select ~r/FROM "(?<table>\w )"/
|
5
|
- @postgrex_insert ~r/INSERT INTO "(?<table>\w )"/
|
6
|
- @postgrex_update ~r/UPDATE "(?<table>\w )"/
|
7
|
- @postgrex_delete ~r/FROM "(?<table>\w )"/
|
8
|
- @postgrex_create_table ~r/CREATE TABLE( IF NOT EXISTS)? "(?<table>\w )"/
|
4
|
def parse(%{result: {:ok, %{__struct__: Postgrex.Cursor}}}), do: :ignore
|
5
|
|
9
6
|
def parse(%{
|
10
7
|
query: query,
|
11
8
|
result: {_ok_or_error, %{__struct__: struct}}
|
12
9
|
})
|
13
10
|
when struct in [Postgrex.Result, Postgrex.Error] do
|
14
|
- {operation, table} =
|
15
|
- case query do
|
16
|
- "SELECT" <> _ -> {"select", capture(@postgrex_select, query, "table")}
|
17
|
- "INSERT" <> _ -> {"insert", capture(@postgrex_insert, query, "table")}
|
18
|
- "UPDATE" <> _ -> {"update", capture(@postgrex_update, query, "table")}
|
19
|
- "DELETE" <> _ -> {"delete", capture(@postgrex_delete, query, "table")}
|
20
|
- "CREATE TABLE" <> _ -> {"create", capture(@postgrex_create_table, query, "table")}
|
21
|
- "begin" -> {"begin", "other"}
|
22
|
- "commit" -> {"commit", "other"}
|
23
|
- "rollback" -> {"rollback", "other"}
|
24
|
- _ -> {"other", "other"}
|
25
|
- end
|
26
|
-
|
27
|
- {"Postgres", table, operation}
|
11
|
{"Postgres", parse_query(query)}
|
28
12
|
end
|
29
13
|
|
30
|
- @myxql_select ~r/FROM `(?<table>\w )`/
|
31
|
- @myxql_insert ~r/INSERT INTO `(?<table>\w )`/
|
32
|
- @myxql_update ~r/UPDATE `(?<table>\w )`/
|
33
|
- @myxql_delete ~r/FROM `(?<table>\w )`/
|
34
|
- @myxql_create_table ~r/CREATE TABLE( IF NOT EXISTS)? `(?<table>\w )`/
|
14
|
def parse(%{result: {:ok, %{__struct__: MyXQL.Cursor}}}), do: :ignore
|
15
|
|
35
16
|
def parse(%{
|
36
17
|
query: query,
|
37
18
|
result: {_ok_or_error, %{__struct__: struct}}
|
38
19
|
})
|
39
20
|
when struct in [MyXQL.Result, MyXQL.Error] do
|
21
|
{"MySQL", parse_query(query)}
|
22
|
end
|
23
|
|
24
|
def parse(%{
|
25
|
query: query,
|
26
|
repo: repo,
|
27
|
result: {_ok_or_error, %{__struct__: _result_struct}}
|
28
|
}) do
|
29
|
[adaapter | _] = repo.__adapter__() |> Module.split() |> Enum.reverse()
|
30
|
{adaapter, parse_query(query)}
|
31
|
end
|
32
|
|
33
|
def parse(%{result: {:ok, _}}), do: :ignore
|
34
|
def parse(%{result: {:error, _}}), do: :ignore
|
35
|
|
36
|
# Escape chars
|
37
|
# Postgrex: "
|
38
|
# MyXQL: `
|
39
|
# Tds: [
|
40
|
# Exqlite: none
|
41
|
@esc ~s(["`\[]?)
|
42
|
|
43
|
@select ~r/FROM #{@esc}(?<table>\w )#{@esc}/
|
44
|
@insert ~r/INSERT INTO #{@esc}(?<table>\w )#{@esc}/
|
45
|
@update ~r/UPDATE #{@esc}(?<table>\w )#{@esc}/
|
46
|
@delete ~r/FROM #{@esc}(?<table>\w )#{@esc}/
|
47
|
@create ~r/CREATE TABLE( IF NOT EXISTS)? #{@esc}(?<table>\w )#{@esc}/
|
48
|
defp parse_query(query) do
|
40
49
|
{operation, table} =
|
41
50
|
case query do
|
42
|
- "SELECT" <> _ -> {"select", capture(@myxql_select, query, "table")}
|
43
|
- "INSERT" <> _ -> {"insert", capture(@myxql_insert, query, "table")}
|
44
|
- "UPDATE" <> _ -> {"update", capture(@myxql_update, query, "table")}
|
45
|
- "DELETE" <> _ -> {"delete", capture(@myxql_delete, query, "table")}
|
46
|
- "CREATE TABLE" <> _ -> {"create", capture(@myxql_create_table, query, "table")}
|
51
|
"SELECT" <> _ -> {"select", capture(@select, query, "table")}
|
52
|
"INSERT" <> _ -> {"insert", capture(@insert, query, "table")}
|
53
|
"UPDATE" <> _ -> {"update", capture(@update, query, "table")}
|
54
|
"DELETE" <> _ -> {"delete", capture(@delete, query, "table")}
|
55
|
"CREATE TABLE" <> _ -> {"create", capture(@create, query, "table")}
|
47
56
|
"begin" -> {"begin", "other"}
|
48
57
|
"commit" -> {"commit", "other"}
|
49
58
|
"rollback" -> {"rollback", "other"}
|
50
59
|
_ -> {"other", "other"}
|
51
60
|
end
|
52
61
|
|
53
|
- {"MySQL", table, operation}
|
62
|
{table, operation}
|
54
63
|
end
|
55
64
|
|
56
|
- def parse(%{result: {:ok, %{__struct__: Postgrex.Cursor}}}), do: :ignore
|
57
|
- def parse(%{result: {:ok, %{__struct__: MyXQL.Cursor}}}), do: :ignore
|
58
|
- def parse(%{result: {:ok, nil}}), do: :ignore
|
59
|
- def parse(%{result: {:error, _}}), do: :ignore
|
60
|
-
|
61
|
- def capture(regex, query, match) do
|
65
|
defp capture(regex, query, match) do
|
62
66
|
Regex.named_captures(regex, query)[match]
|
63
67
|
end
|
64
68
|
end
|