Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Elixir umbrella app, where should logger backend app be added as a dependency?

I have an Elixir umbrella application. The applications under the umbrella use Logger. I want to add a backend (logger_logstash_backend) for :logger application. So, I need to add that as a dependency in deps function in mix file.

In the outermost mix file of the umbrella application, the documentation of deps function states:

Dependencies listed here are available only for this project and cannot be accessed from applications inside the apps folder

That means I have to add the backend module as a dependency for each of the applications under the umbrella. However, doing so causes several problems:

  1. It becomes harder to move out the individual applications as separate libraries later.

  2. The individual applications under the umbrella are not actually dependent on the custom :logger backend module. They're okay with default :console backend. But I want to have an additional backend only for prod environment. Therefore, it's more of a cross-applications concern where I'm forced to add the dependency to each application individually.

Do you know any better strategy? What is it?

like image 350
Ahmad Ferdous Avatar asked Sep 22 '17 15:09

Ahmad Ferdous


2 Answers

Each application should have its own dependencies and configuration.

Problems that you mentioned:

  1. It becomes harder to move out the individual applications as separate libraries later.

If you have configurations inside each app, this actually makes it easier to move out the individual applications out of the umbrella app. As mentioned in the Elixir guides, you simply need to move the app out of the apps/ directory.

  1. The individual applications under the umbrella are not actually dependent on the custom :logger backend module. They're okay with default :console backend. But I want to have an additional backend only for prod environment. Therefore, it's more of a cross-applications concern where I'm forced to add the dependency to each application individually.

If the custom logger backend is required only in production environment, then the apps can add this configuration only to config/prod.exs file and use this only in prod environment.

like image 67
Emil Avatar answered Nov 15 '22 19:11

Emil


Umbrella apps still have global configuration, IIRC. This means that if you do config :logger, backends: [CustomBackend] in one, you'll be configuring for them all.

With that in mind, recently I've been using two alternatives I'm happy with:

  1. set the logger as a global dependency. I tend to use this when all the apps will always use the same backend and configuration. As an example, when I'm using the RingLogger backend and no other.

  2. create a logs app. This may not be acceptable depending on how you are separating the apps. But I do this when I want more granular configuration (e.g. configuring an external logging service). Usually this has extra dependencies and configuration details that are abstracted within that app and don't leak to any other. If necessary, I have all other apps depend on it explicitly. It may seem too much of a hassle but I have some issues with configuring external services in the root app. I don't feel like service-specific dependencies should be a global dependency. Instead hiding them away and abstracting those within a logs app gives transparency and allows me to swap services if necessary.

I'm actually curious about the takes on this since I've been debating on it myself.

like image 23
Fernando Mendes Avatar answered Nov 15 '22 18:11

Fernando Mendes