Vous pouvez certainement passer beaucoup de temps à sur-concevoir ce problème.
Pour les langages avec des implémentations de journalisation canonique, instanciez simplement l'enregistreur canonique directement dans chaque classe.
Pour les langues sans implémentation canonique, essayez de trouver un cadre de façade de journalisation et respectez-le. slf4j est un bon choix en Java.
Personnellement, je préfère m'en tenir à une seule implémentation de journalisation concrète et envoyer tout à syslog. Tous les bons outils d'analyse des journaux sont capables de combiner les journaux sysout de plusieurs serveurs d'applications dans un rapport complet.
Lorsqu'une signature de fonction inclut un ou deux services de dépendances ainsi que des arguments "réels", je place les dépendances en dernier:
int calculateFooBarSum(int foo, int bar, IntegerSummationService svc)
Étant donné que mes systèmes ont tendance à ne comporter que cinq services ou moins, je m'assure toujours que les services sont inclus dans le même ordre sur toutes les signatures de fonction. L'ordre alphabétique est aussi bon que n'importe quel autre. (En plus: le maintien de cette approche méthodologique pour la manipulation des mutex réduira également vos chances de développer des blocages.)
Si vous vous retrouvez à injecter plus d'une douzaine de dépendances dans votre application, le système doit probablement être divisé en sous-systèmes distincts (oserais-je dire des microservices?).