diff --git a/instrumentation/opentelemetry_xandra/CHANGELOG.md b/instrumentation/opentelemetry_xandra/CHANGELOG.md new file mode 100644 index 00000000..47830714 --- /dev/null +++ b/instrumentation/opentelemetry_xandra/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +## v0.2.0 + + * Rename `OpenTelemetryXandra` to `OpentelemetryXandra` (notice the case change) to be in line with other libraries in this collection. + * Rename `OpenTelemetryXandra.setup/1` to `OpentelemetryXandra.attach/1`. + * Rename the `query_parser_fun` type to `operation_parser_fun`. + * Rename the `:query_parser` option to `:operation_parser`. + +## v0.1.0 + +First release. diff --git a/instrumentation/opentelemetry_xandra/README.md b/instrumentation/opentelemetry_xandra/README.md index b14260de..09545a27 100644 --- a/instrumentation/opentelemetry_xandra/README.md +++ b/instrumentation/opentelemetry_xandra/README.md @@ -1,4 +1,4 @@ -# OpenTelemetryXandra +# OpentelemetryXandra This library uses [Telemetry](https://github.com/beam-telemetry/telemetry/) events to create OpenTelemetry Spans for [Xandra](https://github.com/whatyouhide/xandra) queries. @@ -17,6 +17,7 @@ end ## Compatibility Matrix -| OpenTelemetryXandra Version | OpenTelemetry Version | +| OpentelemetryXandra Version | OpenTelemetry Version | | :-------------------------- | :-------------------- | | v0.1.0 | v1.0.0 | +| v0.2.0 | v1.0.0 | diff --git a/instrumentation/opentelemetry_xandra/lib/opentelemetry_xandra.ex b/instrumentation/opentelemetry_xandra/lib/opentelemetry_xandra.ex index 58dae8b1..126a705e 100644 --- a/instrumentation/opentelemetry_xandra/lib/opentelemetry_xandra.ex +++ b/instrumentation/opentelemetry_xandra/lib/opentelemetry_xandra.ex @@ -1,4 +1,4 @@ -defmodule OpenTelemetryXandra do +defmodule OpentelemetryXandra do @moduledoc """ A module to trace Xandra queries with OpenTelemetry. @@ -32,7 +32,7 @@ defmodule OpenTelemetryXandra do See `attach/1` for more information. """ - @type query_parser_fun :: + @type operation_parser_fun :: (String.t() -> {operation :: String.t(), database :: String.t(), table :: String.t()}) @doc """ @@ -47,14 +47,14 @@ defmodule OpenTelemetryXandra do # ... ] - OpenTelemetryXandra.attach() + OpentelemetryXandra.setup() Supervisor.start_link(children, strategy: :one_for_one) end ## Options - * `:query_parser` - a function that takes a query (as a string) and should + * `:operation_parser` - a function that takes a query (as a string) and should return a DB operation string that will be used in the span name. For example, for a query like `INSERT INTO users (id, name) VALUES (1, 'Alice')`, the operation parser could return `INSERT`. The default operation parser @@ -73,8 +73,8 @@ defmodule OpenTelemetryXandra do > option. """ - @spec attach(keyword()) :: :ok | {:error, :already_exists} - def attach(options \\ []) when is_list(options) do + @spec setup(keyword()) :: :ok | {:error, :already_exists} + def setup(options \\ []) when is_list(options) do config = %{ operation_parser: Keyword.get(options, :operation_parser, &parse_operation/1) } @@ -98,13 +98,11 @@ defmodule OpenTelemetryXandra do end defp handle_event(:start, metadata, config) do - dbg(metadata) - attributes = attributes_from_query(metadata.query, config) OpentelemetryTelemetry.start_telemetry_span( @tracer_id, - "#{Map.fetch!(attributes, :db_operation)}", + Map.fetch!(attributes, :"db.operation"), metadata, %{ kind: :client, @@ -148,11 +146,16 @@ defmodule OpenTelemetryXandra do defp attributes_from_query(query, config) when is_struct(query, Xandra.Simple) or is_struct(query, Xandra.Prepared) do - {operation, database, table} = config.query_parser.(query.statement) - - ["db.operation": operation, "db.name": database, "db.sql.table": table] - |> Enum.reject(&match?({_, nil}, &1)) - |> Map.new() + case config.operation_parser.(query.statement) do + {operation, database, table} -> + ["db.operation": operation, "db.name": database, "db.sql.table": table] + |> Enum.reject(&match?({_, nil}, &1)) + |> Map.new() + + other -> + raise ArgumentError, + ":operation_parser must return a tuple with 3 elements, got: #{inspect(other)}" + end end defp attributes_from_query(_meta, _config) do @@ -161,8 +164,9 @@ defmodule OpenTelemetryXandra do defp parse_operation(statement) do case String.trim(statement) do - "SELECT" <> _rest -> "SELECT" - _other -> "UNKNOWN" + "SELECT" <> _rest -> {"SELECT", nil, nil} + "UPDATE" <> _rest -> {"UPDATE", nil, nil} + _other -> {"UNKNOWN", nil, nil} end end end diff --git a/instrumentation/opentelemetry_xandra/mix.exs b/instrumentation/opentelemetry_xandra/mix.exs index 2c18a197..f20adc81 100644 --- a/instrumentation/opentelemetry_xandra/mix.exs +++ b/instrumentation/opentelemetry_xandra/mix.exs @@ -1,7 +1,7 @@ defmodule OpentelemetryXandra.MixProject do use Mix.Project - @version "0.1.0" + @version "0.2.0" @description "Trace Xandra queries with OpenTelemetry." @repo_url "https://github.com/open-telemetry/opentelemetry-erlang-contrib" @folder_url "https://github.com/open-telemetry/opentelemetry-erlang-contrib/tree/main/instrumentation/opentelemetry_xandra" @@ -19,7 +19,7 @@ defmodule OpentelemetryXandra.MixProject do source_url: @folder_url, docs: [ source_url_pattern: "#{@folder_url}/%{path}#L%{line}", - main: "OpenTelemetryXandra", + main: "OpentelemetryXandra", extras: ["README.md"] ], diff --git a/instrumentation/opentelemetry_xandra/test/opentelemetry_xandra_test.exs b/instrumentation/opentelemetry_xandra/test/opentelemetry_xandra_test.exs index b982e29b..de1c1cfc 100644 --- a/instrumentation/opentelemetry_xandra/test/opentelemetry_xandra_test.exs +++ b/instrumentation/opentelemetry_xandra/test/opentelemetry_xandra_test.exs @@ -24,7 +24,7 @@ defmodule OpentelemetryXandraTest do describe "span creation when executing queries" do test "when the query is successful" do - OpenTelemetryXandra.attach() + OpentelemetryXandra.setup() conn = start_supervised!({Xandra, connect_timeout: 5_000}) @@ -44,7 +44,7 @@ defmodule OpentelemetryXandraTest do end test "when the query is a prepared query" do - OpenTelemetryXandra.attach() + OpentelemetryXandra.setup() conn = start_supervised!({Xandra, connect_timeout: 5_000}) @@ -63,5 +63,25 @@ defmodule OpentelemetryXandraTest do assert attributes[:"network.peer.address"] == "127.0.0.1" assert attributes[:"network.peer.port"] == 9042 end + + test "with the :operation_parser option" do + OpentelemetryXandra.setup(operation_parser: fn _query -> {"SELECT", nil, nil} end) + + conn = start_supervised!({Xandra, connect_timeout: 5000}) + + Xandra.execute!(conn, "SELECT * FROM system.local", []) + + assert_receive {:span, span(name: "SELECT") = span} + + assert span(span, :kind) == :client + assert span(span, :status) == OpenTelemetry.status(:ok) + + attributes = :otel_attributes.map(span(span, :attributes)) + assert attributes[:"db.system"] == "cassandra" + assert attributes[:"db.operation"] == "SELECT" + assert attributes[:"server.address"] == "127.0.0.1" + assert attributes[:"network.peer.address"] == "127.0.0.1" + assert attributes[:"network.peer.port"] == 9042 + end end end