Merge branch 'graphql-operation-name-logs' into 'main'
Add GraphQL operation name, user ID and actor name in logs See merge request framasoft/mobilizon!1326
This commit is contained in:
commit
da78410039
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
@ -20,9 +20,9 @@
|
||||
<div class="flex-1">
|
||||
<div class="p-2 flex gap-2">
|
||||
<div class="">
|
||||
<figure class="" v-if="member.parent.avatar">
|
||||
<figure class="h-12 w-12" v-if="member.parent.avatar">
|
||||
<img
|
||||
class="rounded-lg"
|
||||
class="rounded-full w-full h-full object-cover"
|
||||
:src="member.parent.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
|
@ -2,7 +2,7 @@ import gql from "graphql-tag";
|
||||
import { ACTOR_FRAGMENT } from "./actor";
|
||||
|
||||
export const DASHBOARD = gql`
|
||||
query {
|
||||
query Dashboard {
|
||||
dashboard {
|
||||
lastPublicEventPublished {
|
||||
id
|
||||
@ -167,7 +167,7 @@ export const REJECT_RELAY = gql`
|
||||
`;
|
||||
|
||||
export const LANGUAGES = gql`
|
||||
query {
|
||||
query Languages {
|
||||
languages {
|
||||
code
|
||||
name
|
||||
@ -204,7 +204,7 @@ export const ADMIN_SETTINGS_FRAGMENT = gql`
|
||||
`;
|
||||
|
||||
export const ADMIN_SETTINGS = gql`
|
||||
query {
|
||||
query AdminSettings {
|
||||
adminSettings {
|
||||
...adminSettingsFragment
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
paginated
|
||||
backend-pagination
|
||||
backend-filtering
|
||||
:debounce-search="200"
|
||||
:debounce-search="500"
|
||||
v-model:current-page="page"
|
||||
:aria-next-label="t('Next page')"
|
||||
:aria-previous-label="t('Previous page')"
|
||||
@ -72,9 +72,12 @@
|
||||
<AccountGroup v-else :size="48" />
|
||||
<div class="">
|
||||
<div class="prose dark:prose-invert">
|
||||
<strong v-if="props.row.name">{{ props.row.name }}</strong
|
||||
><br v-if="props.row.name" />
|
||||
<small>@{{ props.row.preferredUsername }}</small>
|
||||
<p v-if="props.row.name" class="font-bold mb-0">
|
||||
{{ props.row.name }}
|
||||
</p>
|
||||
<span class="text-sm"
|
||||
>@{{ props.row.preferredUsername }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
@ -117,7 +120,7 @@ import {
|
||||
} from "vue-use-route-query";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useHead } from "@vueuse/head";
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { IGroup } from "@/types/actor";
|
||||
import AccountGroup from "vue-material-design-icons/AccountGroup.vue";
|
||||
@ -126,9 +129,10 @@ const PROFILES_PER_PAGE = 10;
|
||||
|
||||
const { restrictions } = useRestrictions();
|
||||
|
||||
const preferredUsername = useRouteQuery("preferredUsername", "");
|
||||
const name = useRouteQuery("name", "");
|
||||
const domain = useRouteQuery("domain", "");
|
||||
const preferredUsername = ref("");
|
||||
const name = ref("");
|
||||
const domain = ref("");
|
||||
|
||||
const local = useRouteQuery("local", false, booleanTransformer);
|
||||
const suspended = useRouteQuery("suspended", false, booleanTransformer);
|
||||
const page = useRouteQuery("page", 1, integerTransformer);
|
||||
|
@ -20,7 +20,7 @@
|
||||
paginated
|
||||
backend-pagination
|
||||
backend-filtering
|
||||
:debounce-search="200"
|
||||
:debounce-search="500"
|
||||
v-model:current-page="page"
|
||||
:aria-next-label="t('Next page')"
|
||||
:aria-previous-label="t('Previous page')"
|
||||
@ -102,7 +102,7 @@ import RouteName from "@/router/name";
|
||||
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||
import { useQuery } from "@vue/apollo-composable";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useHead } from "@vueuse/head";
|
||||
import {
|
||||
useRouteQuery,
|
||||
@ -115,9 +115,10 @@ import Account from "vue-material-design-icons/Account.vue";
|
||||
|
||||
const PROFILES_PER_PAGE = 10;
|
||||
|
||||
const preferredUsername = useRouteQuery("preferredUsername", "");
|
||||
const name = useRouteQuery("name", "");
|
||||
const domain = useRouteQuery("domain", "");
|
||||
const preferredUsername = ref("");
|
||||
const name = ref("");
|
||||
const domain = ref("");
|
||||
|
||||
const local = useRouteQuery("local", false, booleanTransformer);
|
||||
const suspended = useRouteQuery("suspended", false, booleanTransformer);
|
||||
const page = useRouteQuery("page", 1, integerTransformer);
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<section class="container mx-auto">
|
||||
<h1 class="title">{{ $t("My groups") }}</h1>
|
||||
<h1 class="title">{{ t("My groups") }}</h1>
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
t(
|
||||
"Groups are spaces for coordination and preparation to better organize events and manage your community."
|
||||
)
|
||||
}}
|
||||
@ -13,7 +13,7 @@
|
||||
tag="router-link"
|
||||
variant="primary"
|
||||
:to="{ name: RouteName.CREATE_GROUP }"
|
||||
>{{ $t("Create group") }}</o-button
|
||||
>{{ t("Create group") }}</o-button
|
||||
>
|
||||
</div>
|
||||
<o-loading v-model:active="loading"></o-loading>
|
||||
@ -35,10 +35,10 @@
|
||||
v-show="membershipsPages.total > limit"
|
||||
v-model="page"
|
||||
:per-page="limit"
|
||||
:aria-next-label="$t('Next page')"
|
||||
:aria-previous-label="$t('Previous page')"
|
||||
:aria-page-label="$t('Page')"
|
||||
:aria-current-label="$t('Current page')"
|
||||
:aria-next-label="t('Next page')"
|
||||
:aria-previous-label="t('Previous page')"
|
||||
:aria-page-label="t('Page')"
|
||||
:aria-current-label="t('Current page')"
|
||||
>
|
||||
</o-pagination>
|
||||
</section>
|
||||
@ -51,7 +51,7 @@
|
||||
<div class="img-container" :class="{ webp: supportsWebPFormat }" />
|
||||
<div class="text-center">
|
||||
<p>
|
||||
{{ $t("You are not part of any group.") }}
|
||||
{{ t("You are not part of any group.") }}
|
||||
<i18n-t
|
||||
keypath="Do you wish to {create_group} or {explore_groups}?"
|
||||
>
|
||||
@ -59,14 +59,14 @@
|
||||
<o-button
|
||||
tag="router-link"
|
||||
:to="{ name: RouteName.CREATE_GROUP }"
|
||||
>{{ $t("create a group") }}</o-button
|
||||
>{{ t("create a group") }}</o-button
|
||||
>
|
||||
</template>
|
||||
<template #explore_groups>
|
||||
<o-button
|
||||
tag="router-link"
|
||||
:to="{ name: RouteName.SEARCH }"
|
||||
>{{ $t("explore the groups") }}</o-button
|
||||
>{{ t("explore the groups") }}</o-button
|
||||
>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -21,11 +21,11 @@
|
||||
>
|
||||
<div class="flex gap-1">
|
||||
<div class="flex gap-1">
|
||||
<figure class="" v-if="log.actor?.avatar">
|
||||
<figure class="h-10 w-10" v-if="log.actor?.avatar">
|
||||
<img
|
||||
alt=""
|
||||
:src="log.actor.avatar?.url"
|
||||
class="rounded-full"
|
||||
class="object-cover rounded-full h-full w-full"
|
||||
width="36"
|
||||
height="36"
|
||||
/>
|
||||
|
@ -36,8 +36,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Update do
|
||||
{:ok, activity, entity}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Something went wrong while creating an activity")
|
||||
Logger.debug(inspect(err))
|
||||
Logger.error("Something went wrong while creating an activity", err: inspect(err))
|
||||
{:error, err}
|
||||
end
|
||||
end
|
||||
|
@ -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] ->
|
||||
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}
|
||||
|
||||
|
27
lib/graphql/middleware/operation_name_logger.ex
Normal file
27
lib/graphql/middleware/operation_name_logger.ex
Normal file
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user