Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Persistent Activity Logger #2730

Merged
merged 12 commits into from
Jul 10, 2024
Merged

Add Persistent Activity Logger #2730

merged 12 commits into from
Jul 10, 2024

Conversation

nelsonkopliku
Copy link
Member

@nelsonkopliku nelsonkopliku commented Jul 1, 2024

Description

This PR introduces the ability to track interesting activities in the system.
Initial focus in on tracking http related activities.

Notes:

  • metadata extraction testing has been omitted in PhoenixConnParserTest but tested in ActivityLogger which covers the broader integration of the different components
  • in order to not make the PR even bigger only tests about login activity and tagging/untagging have been added in ActivityLogger. More test about the other interesting activities to follow.

EDIT: Since we currently do not need different kind of destinations where to write logs, a few abstractions have been removed.

How was this tested?

automated tests.

@nelsonkopliku nelsonkopliku self-assigned this Jul 1, 2024
@nelsonkopliku nelsonkopliku added enhancement New feature or request user story elixir Pull requests that update Elixir code labels Jul 1, 2024
Base automatically changed from activity-logger-plug to main July 1, 2024 12:53
@nelsonkopliku nelsonkopliku force-pushed the activity-logger branch 4 times, most recently from 16c8a8a to d2420f0 Compare July 3, 2024 08:01
Comment on lines 8 to 10
@login_attempt {TrentoWeb.SessionController, :create}
@api_key_generation {TrentoWeb.V1.SettingsController, :update_api_key_settings}
@saving_suma_settings {TrentoWeb.V1.SUMACredentialsController, :create}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe for later: Use the OpenAPI spec as a single source of truth for this purpose.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea. Let's indeed keep that on top of our minds as dealing with openapispex schemas would be a beast on its own 😄

lib/trento/activity_logging/registry.ex Outdated Show resolved Hide resolved
@@ -0,0 +1,127 @@
defmodule Trento.ActivityLogging.Logger.PhoenixConnParser do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this potentially be a Protocol?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not think about that, yet. I cannot firmly say yes or no at the moment.
I guess when we introduce the Commanded related activity logging we might discover what it needs to be.

@nelsonkopliku nelsonkopliku force-pushed the activity-logger branch 2 times, most recently from 5f2113b to 4fa886d Compare July 4, 2024 12:00
@nelsonkopliku nelsonkopliku requested a review from balanza July 4, 2024 12:01
@nelsonkopliku nelsonkopliku marked this pull request as ready for review July 4, 2024 12:02
@nelsonkopliku nelsonkopliku added the env Create an ephimeral environment for the pr branch label Jul 4, 2024
Copy link
Contributor

@gagandeepb gagandeepb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, for the most part. Up to you how/when you want to address the comments.

Comment on lines 1 to 23
defmodule Trento.ActivityLog.ActivityCatalog do
@moduledoc """
Activity logging catalog
"""

@type logged_activity :: {controller :: module(), activity :: atom()}

@login_attempt {TrentoWeb.SessionController, :create}
@api_key_generation {TrentoWeb.V1.SettingsController, :update_api_key_settings}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a boundary issue with the Trento name space now depending on TrentoWeb (usually it is the other way around). One way to resolve this would be to create a top-level namespace ActivityLog for all related modules, especially the ones with cross-cutting module dependencies. WDYT ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boundary issue with the Trento name space now depending on TrentoWeb

I hear you, I see what you mean and I tend to agree.

Consider we already break that dependency direction in projectors, enriching commanded middleware and in an amqp message processor (mainly views and TrentoWeb.Endpoint in order to broadcast things via websocket) 🙈

Now, I am not saying that since we broke some rule we should ruthlessly keep doing so 😄
What I mean is that we accepted the trade-off of having access to TrentoWeb components within Trento in certain edgy areas (like projectors and what mentioned earlier).

All the references to TrentoWeb controllers are kept inside the centralized Trento.ActivityLog.ActivityCatalog (meant to be like that) and I would keep accepting this trade-off also for this feature, unless until it matures more.

I will track an item with the concern you're raising.


Solution wide, I guess you mean having a top level ./lib/activity_log (or similar) next to ./lib/trento and ./lib/trento_web. It might make sense indeed, as it would be a cross-cutting concern, as you mentioned.

Gonna track this in the backlog as well.
Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we just move the ActivityCatalog to the web app? It may make sense as it refers to controller operations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 we'd be needing to access TrentoWeb.{WhateverNamespace}.ActivityCatalog from within Trento and we'd be back in the same situation.

Besides, the activity catalog does belong to activity logging better than web, imho, because it would possibly reference also non-web related activity.

lib/trento/activity_logging/activity_catalog.ex Outdated Show resolved Hide resolved
Comment on lines +1 to +20
defmodule Trento.ActivityLog.Parser.ActivityParser do
@moduledoc """
Behavior for activity parsers.
It extracts the activity relevant information from the context.
"""

alias Trento.ActivityLog.ActivityCatalog

@callback detect_activity(activity_context :: any()) :: ActivityCatalog.logged_activity() | nil

@callback get_activity_actor(
activity :: ActivityCatalog.logged_activity(),
activity_context :: any()
) :: any()

@callback get_activity_metadata(
activity :: ActivityCatalog.logged_activity(),
activity_context :: any()
) :: map()
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defprotocol Trento.ActivityLog.ParseToActivity do
  alias Trento.ActivityLog.ActivityCatalog

  def detect_activity(activity_context :: any()) :: ActivityCatalog.logged_activity() | nil

  def get_activity_actor(
              activity :: ActivityCatalog.logged_activity(),
              activity_context :: any()
            ) :: any()

  def get_activity_metadata(
              activity :: ActivityCatalog.logged_activity(),
              activity_context :: any()
            ) :: map()
end

For reference/ consideration. I think this should work.

@@ -0,0 +1,140 @@
defmodule Trento.ActivityLog.Logger.Parser.PhoenixConnParser do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example:

defimpl Trento.ActivityLog.ParseToActivity, for: %Plug.Conn{} do
...
end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the tips on the protocols, might come good as we proceed further

Copy link
Contributor

@gagandeepb gagandeepb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. LGTM.

@nelsonkopliku
Copy link
Member Author

@gagandeepb FYI since we currently do not need different kind of destinations where to write logs, a few abstractions have been removed and the overall implementation slightly simplified.

We can add them later if and when needed.

@nelsonkopliku nelsonkopliku merged commit 727e866 into main Jul 10, 2024
26 checks passed
@nelsonkopliku nelsonkopliku deleted the activity-logger branch July 10, 2024 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
elixir Pull requests that update Elixir code enhancement New feature or request env Create an ephimeral environment for the pr branch user story
Development

Successfully merging this pull request may close these issues.

3 participants