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

[PLATFORM-1689]: Attach to subscription publish events #148

Merged
merged 14 commits into from
Apr 18, 2024
3 changes: 3 additions & 0 deletions .versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
files:
- path: mix.exs
pattern: '@version \"{version}\"'
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

---

## [2.2.2-rc.0] - 2024-04-17

### Added

- Attach to `[:absinthe, :subscription, :publish]` (both `:start` and `:stop`)
- New `graphql.event.type` trace attribute, with value `operation` or `publish`

## [2.2.1] - 2024-02-21

### Changed
Expand Down Expand Up @@ -64,7 +73,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
If you're upgrading to opentelemetry_absinthe 1.1.0, it is therefore recommended to also upgrade to OpenTelemetry API 1.1.0
in order to keep the opentelemetry log metadata.

[Unreleased]: https://github.com/primait/opentelemetry_absinthe/compare/2.0.1...HEAD

[Unreleased]: https://github.com/primait/opentelemetry_absinthe/compare/2.2.2-rc.0...HEAD
[2.2.2-rc.0]: https://github.com/primait/opentelemetry_absinthe/compare/2.2.1...2.2.2-rc.0
[2.0.0]: https://github.com/primait/opentelemetry_absinthe/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/primait/opentelemetry_absinthe/compare/1.1.0...2.0.0
[1.1.0]: https://github.com/primait/opentelemetry_absinthe/compare/1.0.0...1.1.0
30 changes: 24 additions & 6 deletions lib/instrumentation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,40 @@ defmodule OpentelemetryAbsinthe.Instrumentation do
:telemetry.attach(
{__MODULE__, :operation_start},
[:absinthe, :execute, :operation, :start],
&__MODULE__.handle_operation_start/4,
config
&__MODULE__.handle_start/4,
Map.put(config, :type, :operation)
)

:telemetry.attach(
{__MODULE__, :operation_stop},
[:absinthe, :execute, :operation, :stop],
&__MODULE__.handle_operation_stop/4,
config
&__MODULE__.handle_stop/4,
Map.put(config, :type, :operation)
)

:telemetry.attach(
{__MODULE__, :publish_start},
[:absinthe, :subscription, :publish, :start],
&__MODULE__.handle_start/4,
Map.put(config, :type, :publish)
)

:telemetry.attach(
{__MODULE__, :publish_stop},
[:absinthe, :subscription, :publish, :stop],
&__MODULE__.handle_stop/4,
Map.put(config, :type, :publish)
)
end

def teardown do
:telemetry.detach({__MODULE__, :operation_start})
:telemetry.detach({__MODULE__, :operation_stop})
:telemetry.detach({__MODULE__, :publish_start})
:telemetry.detach({__MODULE__, :publish_stop})
end

def handle_operation_start(_event_name, _measurements, metadata, config) do
def handle_start(_event_name, _measurements, metadata, config) do
document = metadata.blueprint.input
variables = metadata |> Map.get(:options, []) |> Keyword.get(:variables, %{})

Expand All @@ -99,6 +115,7 @@ defmodule OpentelemetryAbsinthe.Instrumentation do
{:"graphql.request.variables", Jason.encode!(variables)}
)
|> put_if(config.trace_request_query, {@graphql_document, document})
|> List.insert_at(0, {:"graphql.event.type", config.type})

save_parent_ctx()

Expand All @@ -108,7 +125,7 @@ defmodule OpentelemetryAbsinthe.Instrumentation do
Tracer.set_current_span(new_ctx)
end

def handle_operation_stop(_event_name, measurements, data, config) do
def handle_stop(_event_name, measurements, data, config) do
operation_type = get_operation_type(data)
operation_name = get_operation_name(data)

Expand All @@ -129,6 +146,7 @@ defmodule OpentelemetryAbsinthe.Instrumentation do
config.trace_request_selections,
fn -> {:"graphql.request.selections", data |> get_graphql_selections() |> Jason.encode!()} end
)
|> List.insert_at(0, {:"graphql.event.type", config.type})
|> Tracer.set_attributes()

:telemetry.execute(
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule OpentelemetryAbsinthe.MixProject do
use Mix.Project

@source_url "https://github.com/primait/opentelemetry_absinthe"
@version "2.2.1"
@version "2.2.2-rc.0"

def project do
[
Expand Down
4 changes: 4 additions & 0 deletions test/configuration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule OpentelemetryAbsintheTest.Configuration do
@graphql_operation_name :"graphql.operation.name"
@graphql_operation_type :"graphql.operation.type"
@graphql_request_selections :"graphql.request.selections"
@graphql_event_type :"graphql.event.type"

doctest OpentelemetryAbsinthe.Instrumentation

Expand All @@ -19,6 +20,7 @@ defmodule OpentelemetryAbsintheTest.Configuration do

assert [
@graphql_document,
@graphql_event_type,
@graphql_operation_name,
@graphql_operation_type,
@graphql_request_selections
Expand All @@ -35,6 +37,7 @@ defmodule OpentelemetryAbsintheTest.Configuration do
attributes = Query.query_for_attrs(Queries.query(), variables: %{"isbn" => "A1"})

assert [
@graphql_event_type,
@graphql_operation_name,
@graphql_operation_type,
@graphql_request_selections,
Expand All @@ -53,6 +56,7 @@ defmodule OpentelemetryAbsintheTest.Configuration do

assert [
@graphql_document,
@graphql_event_type,
@graphql_operation_name,
@graphql_operation_type
] = attributes |> Map.keys() |> Enum.sort()
Expand Down
21 changes: 21 additions & 0 deletions test/event_type_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule OpentelemetryAbsintheTest.EvenType do
use OpentelemetryAbsintheTest.Case

alias OpentelemetryAbsintheTest.Support.GraphQL.Queries
alias OpentelemetryAbsintheTest.Support.Query

@graphql_event_type :"graphql.event.type"

doctest OpentelemetryAbsinthe.Instrumentation

test "records operation on query" do
OpentelemetryAbsinthe.Instrumentation.setup()

attributes = Query.query_for_attrs(Queries.query(), variables: %{"isbn" => "A1"})

assert @graphql_event_type in Map.keys(attributes)
assert :operation == Map.get(attributes, @graphql_event_type)
end

# NOTE: a subscription test could go here, but setting up subscription testing just for this didn't seem worth it
end
11 changes: 5 additions & 6 deletions test/instrumentation_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ defmodule OpentelemetryAbsintheTest.Instrumentation do

@trace_attributes [
:"graphql.document",
:"graphql.event.type",
:"graphql.operation.name",
:"graphql.operation.type",
:"graphql.request.selections",
Expand All @@ -22,13 +23,11 @@ defmodule OpentelemetryAbsintheTest.Instrumentation do
:"graphql.response.result"
]

describe "query" do
test "doesn't crash when empty" do
OpentelemetryAbsinthe.Instrumentation.setup(@capture_all)
attrs = Query.query_for_attrs(Queries.empty_query())
test "doesn't crash when query is empty" do
OpentelemetryAbsinthe.Instrumentation.setup(@capture_all)
attrs = Query.query_for_attrs(Queries.empty_query())

assert @trace_attributes = attrs |> Map.keys() |> Enum.sort()
end
assert @trace_attributes = attrs |> Map.keys() |> Enum.sort()
end

test "handles multiple queries properly" do
Expand Down
Loading