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:
Thomas Citharel 2022-11-06 13:47:59 +00:00
commit da78410039
12 changed files with 74 additions and 37 deletions

View file

@ -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",

View file

@ -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

View file

@ -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"

View file

@ -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
}

View file

@ -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);

View file

@ -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);

View file

@ -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>

View file

@ -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"
/>

View file

@ -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

View file

@ -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}

View 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, &current_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

View file

@ -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