From 30b0d3ca08224649ac1f9771bc0474e1070da5dd Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 6 Nov 2022 11:57:53 +0100 Subject: [PATCH] Add GraphQL operation name, user ID and actor name in logs Signed-off-by: Thomas Citharel --- config/config.exs | 2 +- config/dev.exs | 2 +- .../middleware/current_actor_provider.ex | 8 +++++- .../middleware/operation_name_logger.ex | 27 +++++++++++++++++++ lib/graphql/schema.ex | 4 +-- 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 lib/graphql/middleware/operation_name_logger.ex diff --git a/config/config.exs b/config/config.exs index dd5e28b6a..77591db87 100644 --- a/config/config.exs +++ b/config/config.exs @@ -138,7 +138,7 @@ config :vite_phx, config :logger, :console, backends: [:console], format: "$time $metadata[$level] $message\n", - metadata: [:request_id] + metadata: [:request_id, :graphql_operation_name, :user_id, :actor_name] config :mobilizon, Mobilizon.Web.Auth.Guardian, issuer: "mobilizon", diff --git a/config/dev.exs b/config/dev.exs index 77c55e544..6c8418b88 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -48,7 +48,7 @@ config :mobilizon, Mobilizon.Web.Endpoint, ] # Do not include metadata nor timestamps in development logs -config :logger, :console, format: "[$level] $message\n", level: :debug +config :logger, :console, format: "$metadata[$level] $message\n", level: :debug config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim diff --git a/lib/graphql/middleware/current_actor_provider.ex b/lib/graphql/middleware/current_actor_provider.ex index abf7384cc..64037f233 100644 --- a/lib/graphql/middleware/current_actor_provider.ex +++ b/lib/graphql/middleware/current_actor_provider.ex @@ -18,7 +18,13 @@ defmodule Mobilizon.GraphQL.Middleware.CurrentActorProvider do case Cachex.fetch(:default_actors, to_string(user_id), fn -> default(user) end) do {status, %Actor{preferred_username: preferred_username} = current_actor} when status in [:ok, :commit] -> - Sentry.Context.set_user_context(%{name: preferred_username}) + Logger.metadata(user_id: user_id) + Logger.metadata(actor_name: "@" <> preferred_username) + + if Application.get_env(:sentry, :dsn) != nil do + Sentry.Context.set_user_context(%{name: preferred_username}) + end + context = Map.put(context, :current_actor, current_actor) %Absinthe.Resolution{resolution | context: context} diff --git a/lib/graphql/middleware/operation_name_logger.ex b/lib/graphql/middleware/operation_name_logger.ex new file mode 100644 index 000000000..7c0a888da --- /dev/null +++ b/lib/graphql/middleware/operation_name_logger.ex @@ -0,0 +1,27 @@ +defmodule Mobilizon.GraphQL.Middleware.OperationNameLogger do + @moduledoc """ + An Absinthe middleware to add to logging providers the GraphQL Operation name as context + """ + + @behaviour Absinthe.Middleware + alias Absinthe.Blueprint.Document.Operation + + def call(resolution, _opts) do + case Enum.find(resolution.path, ¤t_operation?/1) do + %Operation{name: name} when not is_nil(name) -> + Logger.metadata(graphql_operation_name: name) + + if Application.get_env(:sentry, :dsn) != nil do + Sentry.Context.set_extra_context(%{"graphql_operation_name" => name}) + end + + _ -> + Logger.metadata(graphql_operation_name: "#NULL") + end + + resolution + end + + defp current_operation?(%Operation{current: true}), do: true + defp current_operation?(_), do: false +end diff --git a/lib/graphql/schema.ex b/lib/graphql/schema.ex index e89641b4a..8306808d1 100644 --- a/lib/graphql/schema.ex +++ b/lib/graphql/schema.ex @@ -20,7 +20,7 @@ defmodule Mobilizon.GraphQL.Schema do alias Mobilizon.Actors.{Actor, Follower, Member} alias Mobilizon.Discussions.Comment alias Mobilizon.Events.{Event, Participant} - alias Mobilizon.GraphQL.Middleware.{CurrentActorProvider, ErrorHandler} + alias Mobilizon.GraphQL.Middleware.{CurrentActorProvider, ErrorHandler, OperationNameLogger} alias Mobilizon.GraphQL.Schema alias Mobilizon.GraphQL.Schema.Custom alias Mobilizon.Storage.Repo @@ -199,7 +199,7 @@ defmodule Mobilizon.GraphQL.Schema do @spec middleware(list(module()), any(), map()) :: list(module()) def middleware(middleware, _field, %{identifier: type}) when type in [:query, :mutation] do - [CurrentActorProvider] ++ middleware ++ [ErrorHandler] + [CurrentActorProvider] ++ middleware ++ [ErrorHandler, OperationNameLogger] end def middleware(middleware, _field, _object) do