diff --git a/lib/angen/helpers/fake_data/fake_logging.ex b/lib/angen/helpers/fake_data/fake_logging.ex
index 92ce8ea..f4e2ac8 100644
--- a/lib/angen/helpers/fake_data/fake_logging.ex
+++ b/lib/angen/helpers/fake_data/fake_logging.ex
@@ -69,8 +69,7 @@ defmodule Angen.FakeData.FakeLogging do
"spectator" => rand_int(0, config.max_users / 2, 10),
"player" => rand_int(0, config.max_users / 3, 10),
}
- |> add_total_key(:total_non_bot, [:bot])
- |> add_total_key(:total_bot, [:non_bot])
+ |> add_bot_totals
lobby = %{
"in_progress" => rand_int(0, config.max_users / 2, 10),
@@ -168,27 +167,25 @@ defmodule Angen.FakeData.FakeLogging do
)
|> Enum.count
+ minutes = %{
+ "lobby" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes lobby))),
+ "menu" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes menu))),
+ "player" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes player))),
+ "spectator" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes spectator))),
+ "bot" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes bot)))
+ }
+ |> add_bot_totals
+
%{
"average_user_counts" => %{
"lobby" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24),
"menu" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24),
"player" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24),
"spectator" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24),
- "total" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24)
- },
- "minutes" => add_total_key(%{
- "lobby" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes lobby))),
- "menu" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes menu))),
- "player" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes player))),
- "spectator" => rand_int(config.max_users * 20, config.max_users * 600, get_in(last_day, ~w(minutes spectator)))
- }, "total", []),
- "peak_user_counts" => %{
- "lobby" => rand_int_sequence(config.max_users / 10, config.max_users / 4, 0, 24),
- "menu" => rand_int_sequence(config.max_users / 10, config.max_users / 4, 0, 24),
- "player" => rand_int_sequence(config.max_users / 10, config.max_users / 4, 0, 24),
- "spectator" => rand_int_sequence(config.max_users / 10, config.max_users / 4, 0, 24),
- "total" => rand_int_sequence(config.max_users / 10, config.max_users / 4, 0, 24)
+ "total_inc_bot" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24),
+ "total_non_bot" => rand_int_sequence(config.max_users / 10, config.max_users / 3, 0, 24)
},
+ "minutes" => minutes,
"peak_user_counts" => %{
"bot" => rand_int(10, config.max_users / 3, get_in(last_day, ~w(stats peak_user_counts bot))),
"lobby" => rand_int(10, config.max_users / 3, get_in(last_day, ~w(stats peak_user_counts lobby))),
@@ -196,7 +193,7 @@ defmodule Angen.FakeData.FakeLogging do
"player" => rand_int(10, config.max_users / 3, get_in(last_day, ~w(stats peak_user_counts player))),
"spectator" => rand_int(10, config.max_users / 3, get_in(last_day, ~w(stats peak_user_counts spectator))),
"total" => rand_int(10, config.max_users / 3, get_in(last_day, ~w(stats peak_user_counts total))),
- },
+ } |> add_bot_totals,
"stats" => %{
"accounts_created" => accounts_created,
"unique_users" => rand_int(config.max_users / 10, config.max_users, get_in(last_day, ~w(stats unique_users))),
@@ -204,4 +201,10 @@ defmodule Angen.FakeData.FakeLogging do
}
}
end
+
+ defp add_bot_totals(m) do
+ m
+ |> add_total_key("total_non_bot", ["bot"])
+ |> add_total_key("total_inc_bot", ["total_non_bot"])
+ end
end
diff --git a/lib/angen/helpers/styling_helpers.ex b/lib/angen/helpers/styling_helpers.ex
index 7faf187..2ac67a7 100644
--- a/lib/angen/helpers/styling_helpers.ex
+++ b/lib/angen/helpers/styling_helpers.ex
@@ -56,7 +56,7 @@ defmodule Angen.Helper.StylingHelper do
def icon(:up), do: "fa-level-up"
def icon(:back), do: "fa-arrow-left"
- def icon(:list, _fa_type), do: "fa-bars"
+ def icon(:list), do: "fa-bars"
def icon(:show), do: "fa-eye"
def icon(:search), do: "fa-search"
def icon(:new), do: "fa-plus"
diff --git a/lib/angen/helpers/timex_helper.ex b/lib/angen/helpers/timex_helper.ex
index eed0120..8377569 100644
--- a/lib/angen/helpers/timex_helper.ex
+++ b/lib/angen/helpers/timex_helper.ex
@@ -425,7 +425,8 @@ defmodule Angen.Helper.TimexHelper do
Timex.compare(a, b) == -1
end
- def represent_minutes(nil), do: ""
+ def represent_minutes(nil), do: "0 minutes"
+ def represent_minutes(0), do: "0 minutes"
def represent_minutes(s) do
now = Timex.now()
diff --git a/lib/angen/logging/tasks/persist_server_day_task.ex b/lib/angen/logging/tasks/persist_server_day_task.ex
index 52cab81..998876f 100644
--- a/lib/angen/logging/tasks/persist_server_day_task.ex
+++ b/lib/angen/logging/tasks/persist_server_day_task.ex
@@ -11,7 +11,7 @@ defmodule Angen.Logging.PersistServerDayTask do
@log_keep_days 30
- @client_states ~w(lobby bot menu player spectator total)a
+ @client_states ~w(lobby bot menu player spectator total_non_bot total_inc_bot)a
# [] List means 1 hour segments
# %{} Dict means total for the day for that key
@@ -39,7 +39,8 @@ defmodule Angen.Logging.PersistServerDayTask do
lobby: 0,
menu: 0,
bot: 0,
- total: 0
+ total_non_bot: 0,
+ total_inc_bot: 0
},
# The number of minutes users (combined) spent in that state during the segment
@@ -49,7 +50,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: [],
lobby: [],
menu: [],
- total: []
+ total_non_bot: [],
+ total_inc_bot: []
},
peak_user_counts: %{
bot: [],
@@ -57,7 +59,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: [],
lobby: [],
menu: [],
- total: []
+ total_non_bot: [],
+ total_inc_bot: []
}
}
@@ -82,7 +85,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: 0,
lobby: 0,
menu: 0,
- total: 0
+ total_non_bot: 0,
+ total_inc_bot: 0
},
# The number of minutes users (combined) spent in that state during the segment
@@ -92,7 +96,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: 0,
lobby: 0,
menu: 0,
- total: 0
+ total_non_bot: 0,
+ total_inc_bot: 0
},
peak_user_counts: %{
bot: 0,
@@ -100,7 +105,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: 0,
lobby: 0,
menu: 0,
- total: 0
+ total_non_bot: 0,
+ total_inc_bot: 0
}
}
@@ -196,7 +202,7 @@ defmodule Angen.Logging.PersistServerDayTask do
search: [
after: start_time,
before: end_time,
- node: node
+ # node: node
],
select: [:data],
limit: :infinity
@@ -208,6 +214,7 @@ defmodule Angen.Logging.PersistServerDayTask do
defp extend_segment(segment, logs) do
extend = calculate_segment_parts(logs)
+
%{
# Daily totals
stats: %{
@@ -222,7 +229,9 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: segment.minutes.spectator + extend.minutes.spectator,
lobby: segment.minutes.lobby + extend.minutes.lobby,
menu: segment.minutes.menu + extend.minutes.menu,
- total: segment.minutes.total + extend.minutes.total
+ bot: segment.minutes.bot + extend.minutes.bot,
+ total_non_bot: segment.minutes.total_non_bot + extend.minutes.total_non_bot,
+ total_inc_bot: segment.minutes.total_inc_bot + extend.minutes.total_inc_bot
},
# The number of minutes users (combined) spent in that state during the segment
@@ -232,14 +241,18 @@ defmodule Angen.Logging.PersistServerDayTask do
segment.average_user_counts.spectator ++ [extend.average_user_counts.spectator],
lobby: segment.average_user_counts.lobby ++ [extend.average_user_counts.lobby],
menu: segment.average_user_counts.menu ++ [extend.average_user_counts.menu],
- total: segment.average_user_counts.total ++ [extend.average_user_counts.total]
+ bot: segment.average_user_counts.bot ++ [extend.average_user_counts.bot],
+ total_non_bot: segment.average_user_counts.total_non_bot ++ [extend.average_user_counts.total_non_bot],
+ total_inc_bot: segment.average_user_counts.total_inc_bot ++ [extend.average_user_counts.total_inc_bot]
},
peak_user_counts: %{
player: segment.peak_user_counts.player ++ [extend.peak_user_counts.player],
spectator: segment.peak_user_counts.spectator ++ [extend.peak_user_counts.spectator],
lobby: segment.peak_user_counts.lobby ++ [extend.peak_user_counts.lobby],
menu: segment.peak_user_counts.menu ++ [extend.peak_user_counts.menu],
- total: segment.peak_user_counts.total ++ [extend.peak_user_counts.total]
+ bot: segment.peak_user_counts.bot ++ [extend.peak_user_counts.bot],
+ total_non_bot: segment.peak_user_counts.total_non_bot ++ [extend.peak_user_counts.total_non_bot],
+ total_inc_bot: segment.peak_user_counts.total_inc_bot ++ [extend.peak_user_counts.total_inc_bot]
}
}
end
@@ -251,7 +264,8 @@ defmodule Angen.Logging.PersistServerDayTask do
count = Enum.count(logs)
empty_user_maps = %{
- total: 0,
+ total_non_bot: 0,
+ total_inc_bot: 0,
bot: 0,
player: 0,
spectator: 0,
@@ -264,7 +278,8 @@ defmodule Angen.Logging.PersistServerDayTask do
logs
|> Enum.reduce(empty_user_maps, fn log, acc ->
%{
- total: acc.total + Map.get(log["client"], "total", 0),
+ total_non_bot: acc.bot + Map.get(log["client"], "total_non_bot", 0),
+ total_inc_bot: acc.bot + Map.get(log["client"], "total_inc_bot", 0),
bot: acc.bot + Map.get(log["client"], "bot", 0),
player: acc.player + Map.get(log["client"], "player", 0),
spectator: acc.spectator + Map.get(log["client"], "spectator", 0),
@@ -291,7 +306,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: sum_counts(logs, ~w(client spectator)) / count,
lobby: sum_counts(logs, ~w(client lobby)) / count,
menu: sum_counts(logs, ~w(client menu)) / count,
- total: sum_counts(logs, ~w(client total)) / count
+ total_inc_bot: sum_counts(logs, ~w(client total_inc_bot)) / count,
+ total_non_bot: sum_counts(logs, ~w(client total_non_bot)) / count
},
peak_user_counts: %{
bot: max_counts(logs, ~w(client bot)),
@@ -299,7 +315,8 @@ defmodule Angen.Logging.PersistServerDayTask do
spectator: max_counts(logs, ~w(client spectator)),
lobby: max_counts(logs, ~w(client lobby)),
menu: max_counts(logs, ~w(client menu)),
- total: max_counts(logs, ~w(client total))
+ total_inc_bot: max_counts(logs, ~w(client total_inc_bot)),
+ total_non_bot: max_counts(logs, ~w(client total_non_bot))
}
}
end
@@ -308,7 +325,9 @@ defmodule Angen.Logging.PersistServerDayTask do
end_of_day = Timex.shift(date, days: 1)
Map.put(data, :telemetry, %{
- simple_clientapp: Telemetry.simple_clientapp_events_summary(after: date, before: end_of_day)
+ simple_clientapp: Telemetry.simple_clientapp_events_summary(after: date, before: end_of_day),
+
+ simple_lobby: Telemetry.simple_lobby_events_summary(after: date, before: end_of_day)
})
end
diff --git a/lib/angen/logging/tasks/persist_server_minute_task.ex b/lib/angen/logging/tasks/persist_server_minute_task.ex
index 7f06635..938ff30 100644
--- a/lib/angen/logging/tasks/persist_server_minute_task.ex
+++ b/lib/angen/logging/tasks/persist_server_minute_task.ex
@@ -71,7 +71,7 @@ defmodule Angen.Logging.PersistServerMinuteTask do
{key, Enum.count(values)}
end)
|> add_total_key(:total_non_bot, [:bot])
- |> add_total_key(:total_bot, [:non_bot])
+ |> add_total_key(:total_inc_bot, [:total_non_bot])
end
@spec get_lobby_states() :: map()
diff --git a/lib/angen/telemetry.ex b/lib/angen/telemetry.ex
index d930f5b..e55623c 100644
--- a/lib/angen/telemetry.ex
+++ b/lib/angen/telemetry.ex
@@ -73,7 +73,7 @@ defmodule Angen.Telemetry do
# SimpleClientappEvents
alias Angen.Telemetry.{SimpleClientappEvent, SimpleClientappEventLib, SimpleClientappEventQueries}
- @doc section: :event_type
+ @doc section: :simple_clientapp_event
@spec log_simple_clientapp_event(String.t(), Teiserver.user_id()) :: :ok | {:error, String.t()}
defdelegate log_simple_clientapp_event(name, user_id), to: SimpleClientappEventLib
@@ -81,9 +81,31 @@ defmodule Angen.Telemetry do
@spec simple_clientapp_event_query(Angen.query_args()) :: Ecto.Query.t()
defdelegate simple_clientapp_event_query(args), to: SimpleClientappEventQueries
+ @doc section: :simple_clientapp_event
@spec list_simple_clientapp_events(Teiserver.query_args()) :: [SimpleClientappEvent.t()]
defdelegate list_simple_clientapp_events(args), to: SimpleClientappEventLib
+ @doc section: :simple_clientapp_event
@spec simple_clientapp_events_summary(list) :: map()
defdelegate simple_clientapp_events_summary(args), to: SimpleClientappEventQueries
+
+
+ # SimpleLobbyEvents
+ alias Angen.Telemetry.{SimpleLobbyEvent, SimpleLobbyEventLib, SimpleLobbyEventQueries}
+
+ @doc section: :simple_lobby_event
+ @spec log_simple_lobby_event(String.t(), Teiserver.match_id(), Teiserver.user_id()) :: :ok | {:error, String.t()}
+ defdelegate log_simple_lobby_event(name, match_id, user_id \\ nil), to: SimpleLobbyEventLib
+
+ @doc false
+ @spec simple_lobby_event_query(Angen.query_args()) :: Ecto.Query.t()
+ defdelegate simple_lobby_event_query(args), to: SimpleLobbyEventQueries
+
+ @doc section: :simple_lobby_event
+ @spec list_simple_lobby_events(Teiserver.query_args()) :: [SimpleLobbyEvent.t()]
+ defdelegate list_simple_lobby_events(args), to: SimpleLobbyEventLib
+
+ @doc section: :simple_lobby_event
+ @spec simple_lobby_events_summary(list) :: map()
+ defdelegate simple_lobby_events_summary(args), to: SimpleLobbyEventQueries
end
diff --git a/lib/angen/telemetry/libs/simple_clientapp_event_lib.ex b/lib/angen/telemetry/libs/simple_clientapp_event_lib.ex
index 870200b..9ba5b08 100644
--- a/lib/angen/telemetry/libs/simple_clientapp_event_lib.ex
+++ b/lib/angen/telemetry/libs/simple_clientapp_event_lib.ex
@@ -22,14 +22,6 @@ defmodule Angen.Telemetry.SimpleClientappEventLib do
case create_simple_clientapp_event(attrs) do
{:ok, _event} -> :ok
{:error, changeset} ->
- IO.puts "#{__MODULE__}:#{__ENV__.line}"
- IO.inspect attrs
- IO.puts ""
-
- IO.puts "#{__MODULE__}:#{__ENV__.line}"
- IO.inspect changeset
- IO.puts ""
-
{:error,
changeset.errors
|> Enum.map_join(", ", fn {key, {message, _}} ->
diff --git a/lib/angen/telemetry/libs/simple_lobby_event_lib.ex b/lib/angen/telemetry/libs/simple_lobby_event_lib.ex
new file mode 100644
index 0000000..9db2e62
--- /dev/null
+++ b/lib/angen/telemetry/libs/simple_lobby_event_lib.ex
@@ -0,0 +1,164 @@
+defmodule Angen.Telemetry.SimpleLobbyEventLib do
+ @moduledoc """
+ Library of simple_lobby_event related functions.
+ """
+ use TeiserverMacros, :library
+ alias Angen.Telemetry
+ alias Angen.Telemetry.{SimpleLobbyEvent, SimpleLobbyEventQueries}
+
+ @doc """
+ A wrapper around create_simple_lobby_event which handles grabbing the event_type_id
+ """
+ @spec log_simple_lobby_event(String.t(), Teiserver.match_id(), Teiserver.user_id()) :: :ok | {:error, String.t()}
+ def log_simple_lobby_event(name, match_id, user_id \\ nil) do
+ type_id = Telemetry.get_or_add_event_type_id(name, "simple_lobby")
+
+ attrs = %{
+ event_type_id: type_id,
+ match_id: match_id,
+ user_id: user_id,
+ inserted_at: Timex.now()
+ }
+
+ case create_simple_lobby_event(attrs) do
+ {:ok, _event} -> :ok
+ {:error, changeset} ->
+ {:error,
+ changeset.errors
+ |> Enum.map_join(", ", fn {key, {message, _}} ->
+ "#{key}: #{message}"
+ end)
+ }
+ end
+ end
+
+ @doc """
+ Returns the list of simple_lobby_events.
+
+ ## Examples
+
+ iex> list_simple_lobby_events()
+ [%SimpleLobbyEvent{}, ...]
+
+ """
+ @spec list_simple_lobby_events(Teiserver.query_args()) :: [SimpleLobbyEvent.t()]
+ def list_simple_lobby_events(query_args) do
+ query_args
+ |> SimpleLobbyEventQueries.simple_lobby_event_query()
+ |> Repo.all()
+ end
+
+ @doc """
+ Gets a single simple_lobby_event.
+
+ Raises `Ecto.NoResultsError` if the SimpleLobbyEvent does not exist.
+
+ ## Examples
+
+ iex> get_simple_lobby_event!(123)
+ %SimpleLobbyEvent{}
+
+ iex> get_simple_lobby_event!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ @spec get_simple_lobby_event!(SimpleLobbyEvent.id()) :: SimpleLobbyEvent.t()
+ @spec get_simple_lobby_event!(SimpleLobbyEvent.id(), Teiserver.query_args()) :: SimpleLobbyEvent.t()
+ def get_simple_lobby_event!(simple_lobby_event_id, query_args \\ []) do
+ (query_args ++ [id: simple_lobby_event_id])
+ |> SimpleLobbyEventQueries.simple_lobby_event_query()
+ |> Repo.one!()
+ end
+
+ @doc """
+ Gets a single simple_lobby_event.
+
+ Returns nil if the SimpleLobbyEvent does not exist.
+
+ ## Examples
+
+ iex> get_simple_lobby_event(123)
+ %SimpleLobbyEvent{}
+
+ iex> get_simple_lobby_event(456)
+ nil
+
+ """
+ @spec get_simple_lobby_event(SimpleLobbyEvent.id()) :: SimpleLobbyEvent.t() | nil
+ @spec get_simple_lobby_event(SimpleLobbyEvent.id(), Teiserver.query_args()) :: SimpleLobbyEvent.t() | nil
+ def get_simple_lobby_event(simple_lobby_event_id, query_args \\ []) do
+ (query_args ++ [id: simple_lobby_event_id])
+ |> SimpleLobbyEventQueries.simple_lobby_event_query()
+ |> Repo.one()
+ end
+
+ @doc """
+ Creates a simple_lobby_event.
+
+ ## Examples
+
+ iex> create_simple_lobby_event(%{field: value})
+ {:ok, %SimpleLobbyEvent{}}
+
+ iex> create_simple_lobby_event(%{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ @spec create_simple_lobby_event(map) :: {:ok, SimpleLobbyEvent.t()} | {:error, Ecto.Changeset.t()}
+ def create_simple_lobby_event(attrs) do
+ %SimpleLobbyEvent{}
+ |> SimpleLobbyEvent.changeset(attrs)
+ |> Repo.insert()
+ end
+
+ @doc """
+ Updates a simple_lobby_event.
+
+ ## Examples
+
+ iex> update_simple_lobby_event(simple_lobby_event, %{field: new_value})
+ {:ok, %SimpleLobbyEvent{}}
+
+ iex> update_simple_lobby_event(simple_lobby_event, %{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ @spec update_simple_lobby_event(SimpleLobbyEvent.t(), map) ::
+ {:ok, SimpleLobbyEvent.t()} | {:error, Ecto.Changeset.t()}
+ def update_simple_lobby_event(%SimpleLobbyEvent{} = simple_lobby_event, attrs) do
+ simple_lobby_event
+ |> SimpleLobbyEvent.changeset(attrs)
+ |> Repo.update()
+ end
+
+ @doc """
+ Deletes a simple_lobby_event.
+
+ ## Examples
+
+ iex> delete_simple_lobby_event(simple_lobby_event)
+ {:ok, %SimpleLobbyEvent{}}
+
+ iex> delete_simple_lobby_event(simple_lobby_event)
+ {:error, %Ecto.Changeset{}}
+
+ """
+ @spec delete_simple_lobby_event(SimpleLobbyEvent.t()) :: {:ok, SimpleLobbyEvent.t()} | {:error, Ecto.Changeset.t()}
+ def delete_simple_lobby_event(%SimpleLobbyEvent{} = simple_lobby_event) do
+ Repo.delete(simple_lobby_event)
+ end
+
+ @doc """
+ Returns an `%Ecto.Changeset{}` for tracking simple_lobby_event changes.
+
+ ## Examples
+
+ iex> change_simple_lobby_event(simple_lobby_event)
+ %Ecto.Changeset{data: %SimpleLobbyEvent{}}
+
+ """
+ @spec change_simple_lobby_event(SimpleLobbyEvent.t(), map) :: Ecto.Changeset.t()
+ def change_simple_lobby_event(%SimpleLobbyEvent{} = simple_lobby_event, attrs \\ %{}) do
+ SimpleLobbyEvent.changeset(simple_lobby_event, attrs)
+ end
+end
diff --git a/lib/angen/telemetry/queries/simple_lobby_event_queries.ex b/lib/angen/telemetry/queries/simple_lobby_event_queries.ex
new file mode 100644
index 0000000..16368e6
--- /dev/null
+++ b/lib/angen/telemetry/queries/simple_lobby_event_queries.ex
@@ -0,0 +1,105 @@
+defmodule Angen.Telemetry.SimpleLobbyEventQueries do
+ @moduledoc false
+ use TeiserverMacros, :queries
+ alias Angen.Telemetry.SimpleLobbyEvent
+ require Logger
+
+ @spec simple_lobby_event_query(Teiserver.query_args()) :: Ecto.Query.t()
+ def simple_lobby_event_query(args) do
+ query = from(simple_lobby_events in SimpleLobbyEvent)
+
+ query
+ |> do_where(id: args[:id])
+ |> do_where(args[:where])
+ |> do_where(args[:search])
+ |> do_order_by(args[:order_by])
+ |> QueryHelper.query_select(args[:select])
+ |> QueryHelper.limit_query(args[:limit] || 50)
+ end
+
+ @spec do_where(Ecto.Query.t(), list | map | nil) :: Ecto.Query.t()
+ defp do_where(query, nil), do: query
+
+ defp do_where(query, params) do
+ params
+ |> Enum.reduce(query, fn {key, value}, query_acc ->
+ _where(query_acc, key, value)
+ end)
+ end
+
+ @spec _where(Ecto.Query.t(), Atom.t(), any()) :: Ecto.Query.t()
+ def _where(query, _, ""), do: query
+ def _where(query, _, nil), do: query
+
+ def _where(query, :id, id) do
+ from(simple_lobby_events in query,
+ where: simple_lobby_events.id in ^List.wrap(id)
+ )
+ end
+
+ def _where(query, :type_id, type_id) do
+ from(simple_lobby_events in query,
+ where: simple_lobby_events.type_id in ^List.wrap(type_id)
+ )
+ end
+
+ def _where(query, :user_id, user_id) do
+ from(simple_lobby_events in query,
+ where: simple_lobby_events.user_id in ^List.wrap(user_id)
+ )
+ end
+
+ def _where(query, :lobby_id, lobby_id) do
+ from(simple_lobby_events in query,
+ where: simple_lobby_events.lobby_id in ^List.wrap(lobby_id)
+ )
+ end
+
+ def _where(query, :after, timestamp) do
+ from simple_lobby_events in query,
+ where: simple_lobby_events.inserted_at > ^Timex.to_datetime(timestamp)
+ end
+
+ def _where(query, :before, timestamp) do
+ from simple_lobby_events in query,
+ where: simple_lobby_events.inserted_at < ^Timex.to_datetime(timestamp)
+ end
+
+ @spec do_order_by(Ecto.Query.t(), list | nil) :: Ecto.Query.t()
+ defp do_order_by(query, nil), do: query
+
+ defp do_order_by(query, params) do
+ params
+ |> List.wrap()
+ |> Enum.reduce(query, fn key, query_acc ->
+ _order_by(query_acc, key)
+ end)
+ end
+
+ @spec _order_by(Ecto.Query.t(), any()) :: Ecto.Query.t()
+ def _order_by(query, "Newest first") do
+ from(simple_lobby_events in query,
+ order_by: [desc: simple_lobby_events.inserted_at]
+ )
+ end
+
+ def _order_by(query, "Oldest first") do
+ from(simple_lobby_events in query,
+ order_by: [asc: simple_lobby_events.inserted_at]
+ )
+ end
+
+ @spec simple_lobby_events_summary(list) :: map()
+ def simple_lobby_events_summary(args) do
+ query =
+ from simple_lobby_events in SimpleLobbyEvent,
+ join: event_types in assoc(simple_lobby_events, :event_type),
+ group_by: event_types.name,
+ select: {event_types.name, count(simple_lobby_events.event_type_id)}
+
+ query
+ |> do_where(args)
+ |> Repo.all()
+ |> Map.new()
+ end
+end
diff --git a/lib/angen/telemetry/schemas/complex_lobby_event.ex b/lib/angen/telemetry/schemas/complex_lobby_event.ex
index 3906b9f..18a1072 100644
--- a/lib/angen/telemetry/schemas/complex_lobby_event.ex
+++ b/lib/angen/telemetry/schemas/complex_lobby_event.ex
@@ -15,7 +15,7 @@ defmodule Angen.Telemetry.ComplexLobbyEvent do
schema "telemetry_complex_lobby_events" do
belongs_to(:user, Teiserver.Account.User, type: Ecto.UUID)
- belongs_to(:match_id, Teiserver.Game.Match)
+ belongs_to(:match, Teiserver.Game.Match, type: Ecto.UUID)
belongs_to(:event_type, Angen.Telemetry.EventType)
field(:inserted_at, :utc_datetime)
diff --git a/lib/angen/telemetry/schemas/complex_match_event.ex b/lib/angen/telemetry/schemas/complex_match_event.ex
index 4320288..8e743b9 100644
--- a/lib/angen/telemetry/schemas/complex_match_event.ex
+++ b/lib/angen/telemetry/schemas/complex_match_event.ex
@@ -16,7 +16,7 @@ defmodule Angen.Telemetry.ComplexMatchEvent do
schema "telemetry_complex_anon_events" do
belongs_to(:user, Teiserver.Account.User, type: Ecto.UUID)
- belongs_to(:match_id, Teiserver.Game.Match)
+ belongs_to(:match, Teiserver.Game.Match, type: Ecto.UUID)
belongs_to(:event_type, Angen.Telemetry.EventType)
field(:inserted_at, :utc_datetime)
diff --git a/lib/angen/telemetry/schemas/simple_lobby_event.ex b/lib/angen/telemetry/schemas/simple_lobby_event.ex
index ee8997c..246fa5e 100644
--- a/lib/angen/telemetry/schemas/simple_lobby_event.ex
+++ b/lib/angen/telemetry/schemas/simple_lobby_event.ex
@@ -5,7 +5,7 @@ defmodule Angen.Telemetry.SimpleLobbyEvent do
### Attributes
- * `:user_id` - The `Teiserver.Account.User` this event took place for
+ * `:user_id` - The `Teiserver.Account.User` this event took place for (nullable)
* `:match_id` - The match_id of the lobby this took place in
* `:event_type_id` - The `Angen.Telemetry.EventType` this event belongs to
* `:inserted_at` - The timestamp the event took place
@@ -14,7 +14,7 @@ defmodule Angen.Telemetry.SimpleLobbyEvent do
schema "telemetry_simple_lobby_events" do
belongs_to(:user, Teiserver.Account.User, type: Ecto.UUID)
- belongs_to(:match_id, Teiserver.Game.Match)
+ belongs_to(:match, Teiserver.Game.Match, type: Ecto.UUID)
belongs_to(:event_type, Angen.Telemetry.EventType)
field(:inserted_at, :utc_datetime)
end
@@ -34,6 +34,6 @@ defmodule Angen.Telemetry.SimpleLobbyEvent do
def changeset(struct, attrs \\ %{}) do
struct
|> cast(attrs, ~w(user_id match_id event_type_id inserted_at)a)
- |> validate_required(~w(user_id match_id event_type_id inserted_at)a)
+ |> validate_required(~w(match_id event_type_id inserted_at)a)
end
end
diff --git a/lib/angen/telemetry/schemas/simple_match_event.ex b/lib/angen/telemetry/schemas/simple_match_event.ex
index 956ec88..e8fd052 100644
--- a/lib/angen/telemetry/schemas/simple_match_event.ex
+++ b/lib/angen/telemetry/schemas/simple_match_event.ex
@@ -15,7 +15,7 @@ defmodule Angen.Telemetry.SimpleMatchEvent do
schema "telemetry_simple_anon_events" do
belongs_to(:user, Teiserver.Account.User, type: Ecto.UUID)
- belongs_to(:match_id, Teiserver.Game.Match)
+ belongs_to(:match, Teiserver.Game.Match, type: Ecto.UUID)
belongs_to(:event_type, Angen.Telemetry.EventType)
field(:inserted_at, :utc_datetime)
diff --git a/lib/angen/telemetry/servers/angen_collector_server.ex b/lib/angen/telemetry/servers/angen_collector_server.ex
index 8e1c3f4..7486efa 100644
--- a/lib/angen/telemetry/servers/angen_collector_server.ex
+++ b/lib/angen/telemetry/servers/angen_collector_server.ex
@@ -51,12 +51,12 @@ defmodule Angen.Telemetry.AngenCollectorServer do
# end
def handle_info({:emit, _event, _measurement, _meta, _opts} = msg, state) do
- IO.puts "#{__MODULE__}:#{__ENV__.line}"
- IO.inspect "No telemetry handler for event: #{inspect elem(msg, 1)}"
- IO.inspect elem(msg, 2), label: "Measurement: "
- IO.inspect elem(msg, 3), label: "Meta: "
- IO.inspect elem(msg, 4), label: "Opts: "
- IO.puts ""
+ # IO.puts "#{__MODULE__}:#{__ENV__.line}"
+ # IO.inspect "No telemetry handler for event: #{inspect elem(msg, 1)}"
+ # IO.inspect elem(msg, 2), label: "Measurement: "
+ # IO.inspect elem(msg, 3), label: "Meta: "
+ # IO.inspect elem(msg, 4), label: "Opts: "
+ # IO.puts ""
{:noreply, state}
end
diff --git a/lib/angen/telemetry/servers/teiserver_collector_server.ex b/lib/angen/telemetry/servers/teiserver_collector_server.ex
index 401e8c8..a210e42 100644
--- a/lib/angen/telemetry/servers/teiserver_collector_server.ex
+++ b/lib/angen/telemetry/servers/teiserver_collector_server.ex
@@ -47,6 +47,7 @@ defmodule Angen.Telemetry.TeiserverCollectorServer do
{:noreply, %{state | client_disconnect_counter: new_counter}}
end
+ # Lobby events
def handle_info({:emit, [:teiserver, :lobby, :event], %{type: type}, _meta, _opts}, state) do
new_count = Map.get(state.lobby_event_counter, type, 0) + 1
new_counter = Map.put(state.lobby_event_counter, type, new_count)
@@ -54,6 +55,24 @@ defmodule Angen.Telemetry.TeiserverCollectorServer do
{:noreply, %{state | lobby_event_counter: new_counter}}
end
+ def handle_info({:emit, [:teiserver, :lobby, :cycle], data, meta, _opts}, state) do
+ new_count = Map.get(state.lobby_event_counter, :cycle, 0) + 1
+ new_counter = Map.put(state.lobby_event_counter, :cycle, new_count)
+
+ :ok = Telemetry.log_simple_lobby_event("cycle", meta.match_id, meta[:user_id])
+
+ {:noreply, %{state | lobby_event_counter: new_counter}}
+ end
+
+ def handle_info({:emit, [:teiserver, :lobby, :start_match], _, meta, _opts}, state) do
+ new_count = Map.get(state.lobby_event_counter, :start_match, 0) + 1
+ new_counter = Map.put(state.lobby_event_counter, :start_match, new_count)
+
+ :ok = Telemetry.log_simple_lobby_event("start_match", meta.match_id, meta[:user_id])
+
+ {:noreply, %{state | lobby_event_counter: new_counter}}
+ end
+
def handle_info({:emit, _event, _measurement, _meta, _opts} = _msg, state) do
# IO.puts "#{__MODULE__}:#{__ENV__.line}"
# IO.inspect "No telemetry handler for"
diff --git a/lib/angen_web/components/logging/server_components.ex b/lib/angen_web/components/logging/server_components.ex
index 4e2dd6d..babe308 100644
--- a/lib/angen_web/components/logging/server_components.ex
+++ b/lib/angen_web/components/logging/server_components.ex
@@ -81,10 +81,6 @@ defmodule AngenWeb.Logging.ServerComponents do
Peaks
-
- Total |
- <%= @data["peak_user_counts"]["total"] %> |
-
Player |
<%= @data["peak_user_counts"]["player"] %> |
@@ -93,6 +89,22 @@ defmodule AngenWeb.Logging.ServerComponents do
Spectator |
<%= @data["peak_user_counts"]["spectator"] %> |
+
+ Lobby |
+ <%= @data["peak_user_counts"]["lobby"] %> |
+
+
+ Menu |
+ <%= @data["peak_user_counts"]["menu"] %> |
+
+
+ Bot |
+ <%= @data["peak_user_counts"]["bot"] %> |
+
+
+ Total (no bots) |
+ <%= @data["peak_user_counts"]["total_non_bot"] %> |
+
@@ -103,10 +115,6 @@ defmodule AngenWeb.Logging.ServerComponents do
Time
-
- Total |
- <%= represent_minutes(@data["minutes"]["total"]) %> |
-
Player |
<%= represent_minutes(@data["minutes"]["player"]) %> |
@@ -115,6 +123,22 @@ defmodule AngenWeb.Logging.ServerComponents do
Spectator |
<%= represent_minutes(@data["minutes"]["spectator"]) %> |
+
+ Lobby |
+ <%= represent_minutes(@data["minutes"]["lobby"]) %> |
+
+
+ Menu |
+ <%= represent_minutes(@data["minutes"]["menu"]) %> |
+
+
+ Bot |
+ <%= represent_minutes(@data["minutes"]["bot"]) %> |
+
+
+ Total (no bots) |
+ <%= represent_minutes(@data["minutes"]["total_non_bot"]) %> |
+
@@ -124,7 +148,21 @@ defmodule AngenWeb.Logging.ServerComponents do
<.card>
-
Simple Clientapp events
+ Server events
+
+
+
+
+
+ <.card>
+
Anon events
+
+
+
+
+
+ <.card>
+
Clientapp events
@@ -138,14 +176,21 @@ defmodule AngenWeb.Logging.ServerComponents do
<.card>
-
...
-
+
Lobby events
+
+
+
+ <%= event %> |
+ <%= StringHelper.format_number(count) %> |
+
+
+
<.card>
-
...
+ Match events
diff --git a/lib/angen_web/live/admin/logging/server/now_live.ex b/lib/angen_web/live/admin/logging/server/now_live.ex
index ad3bb64..223edcb 100644
--- a/lib/angen_web/live/admin/logging/server/now_live.ex
+++ b/lib/angen_web/live/admin/logging/server/now_live.ex
@@ -10,13 +10,17 @@ defmodule AngenWeb.Admin.Logging.Server.NowLive do
|> assign(:site_menu_active, "logging")
|> assign(:resolution, Map.get(params, "resolution", "1") |> String.to_integer())
|> assign(:minutes, Map.get(params, "minutes", "30") |> String.to_integer())
- |> generate_graph_data
+ |> assign(:mode, "this_minute")
+ |> get_logs
+ # |> generate_graph_data
{:ok, socket}
end
def mount(_params, _session, socket) do
- {:ok, socket}
+ {:ok, socket
+ |> assign(:mode, "this_minute")
+ }
end
@impl true
@@ -29,20 +33,25 @@ defmodule AngenWeb.Admin.Logging.Server.NowLive do
{:noreply, socket}
end
- defp generate_graph_data(%{assigns: %{resolution: resolution, minutes: minutes}} = socket) do
+ defp get_logs(%{assigns: %{minutes: _minutes}} = socket) do
start_timestamp = nil
logs =
Logging.list_server_minute_logs(
- order: "Oldest first",
+ order: "Newest first",
where: [
# node: "all",
after: start_timestamp
],
limit: 10
)
- |> Enum.group_by(fn log -> log.node end)
+ |> Enum.reverse
+
+ socket
+ |> assign(:logs, logs)
+ end
+ defp generate_graph_data(%{assigns: %{logs: logs}} = socket) do
socket
|> assign(column_clients: GraphMinuteLogsTask.perform_clients(logs, 1))
# |> assign(columns_matches: GraphMinuteLogsTask.perform_matches(logs, 1))
diff --git a/lib/angen_web/live/admin/logging/server/now_live.html.heex b/lib/angen_web/live/admin/logging/server/now_live.html.heex
index 7368af9..2ce457e 100644
--- a/lib/angen_web/live/admin/logging/server/now_live.html.heex
+++ b/lib/angen_web/live/admin/logging/server/now_live.html.heex
@@ -1,6 +1,45 @@
+<%
+ mode_items = ~w(graphs table this_minute)
+ |> Enum.map(fn i ->
+ %{
+ click: "set-mode:#{i}",
+ label: String.capitalize(i) |> String.replace("_", " "),
+ selected: assigns[:mode] == i,
+ }
+ end)
+%>
+
+
+ <.dropdown
+ items={mode_items}
+ label={@mode |> String.replace("_", " ")}
+ />
+<%= if assigns[:logs] != nil and not Enum.empty?(@logs) do %>
+ <%= case @mode do %>
+ <% "this_minute" -> %>
+ <% first_log = hd(@logs) %>
+
+
+
+ <.card>
+
+
+
+
+
+
+
+
+ <% end %>
+<% end %>
+
+
+
+
+<%= if false do %>