26

我有项目com.samedhi/base有一个logback.xml文件和项目com.samedhi/derive也有一个logback.xml文件。项目“派生”依赖于“基础”。当我lein trampoline repl在“派生”上“”时,我收到以下警告。

....
15:34:30,066 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
15:34:30,066 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
15:34:30,066 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/home/stephen/Work/com.samedhi/derive/client/config/logback.xml]
15:34:30,067 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath.
15:34:30,067 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [jar:file:/home/stephen/.m2/repository/com/samedhi/base.app/0.0.1-SNAPSHOT/base.app-0.0.1-SNAPSHOT.jar!/logback.xml]
15:34:30,067 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/home/stephen/Work/com.samedhi/derive/client/config/logback.xml]
15:34:30,129 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
....

所以,问题似乎是我的类路径中有两个 logback.xml。当我从“派生”项目中提取 repl时,我应该怎么做才能从项目“ base ”中“压制” logback.xml ?

4

5 回答 5

21

就我而言,你永远不应该将日志配置文件(logback.xml、log4j.properties 或你有的)打包到 JAR 文件中。甚至拥有日志配置文件的全部意义在于使最终用户可以通过编辑文件轻松调整日志级别。将它埋在档案中违背了这样做的目的,因为要更改日志记录级别,您的用户必须扩展档案,编辑文件,然后重新打包档案。

这是部署应用程序的首选布局。设置起来需要更多的工作,但 IMO 值得麻烦,因为它为您提供了 uberjar 所没有的灵活性和易于配置。

my-app/
  bin/
    run-app.sh
  config/
    logback.xml
  lib/
    my-lib.jar
    my-app.jar

您的run-app.sh脚本将类似于:

BIN=`dirname "$0"`
BASE=$BIN/..
java -cp "$BASE/config:$BASE/lib/*" my-app.main

这样做的好处是,通过将配置目录放在类路径的前面,在那里找到的任何日志记录配置文件都应该优先于可能在其中一个 JAR 中找到的任何内容(例如,包含在您拥有的第三方库中)无法控制)。

于 2013-08-16T14:41:30.873 回答
3

如果基础是一个库,它不应该带有 logback.xml。为什么图书馆关心日志记录?如果它是一个应用程序,您可能应该将公共部分提取到一个库中——base-common——和一个小应用程序——base-app。那么base-common不包含任何 logback 配置。base-appderived都依赖于base-common。他们可以指定他们的 logback 配置而不会发生冲突。

于 2013-08-16T05:52:05.453 回答
2

我想回答我自己的问题,因为我是在 Clojure 的上下文中专门询问的(尽管我在原始问题中完全没有提到这一点,天才)。

我按照 Alex(已接受的答案)的建议解决了这个问题,并将我的 logback.xml 放在它自己的特殊目录dev-config中。然后我使用 clojure 的project.clj文件来指定dev-config只应在开发配置文件运行时加载,如下所示:

;; project.clj
(defproject com.samedhi/base.app "0.0.1-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :profiles {:dev {:source-paths ["dev", "dev-config"]}}
  :min-lein-version "2.0.0"
  :source-paths ["app/src" "app/templates"]
  :resource-paths ["config"]
  :target-path "out/"
  :compiler-options {:externs ["app/externs/base.js"]}
  :aliases {"dumbrepl" ["trampoline" "run" "-m" "clojure.main/main"]})

唯一重要的一点是:profiles => :dev => :source-paths已将“dev-config”添加到其向量中。这个目录是在我进行本地开发时被拾取的,但它不是创建的 jar 文件的一部分,因此不会出现在导入这个项目的其他项目中。因此,在此项目上进行开发时会显示日志记录,但当该项目被其他项目使用时不会显示。出色的。

于 2013-08-17T19:30:55.933 回答
1

我发现亚历克斯策略是有效的。我想添加一个小提示:您可以创建一个 common-config 项目,其中放入可编辑的通用配置文件(例如 logback.xml 等)。将生成的工件添加为所有项目中的依赖项,范围为提供

这将允许您在编译/测试时使用 logback.xml(来自 Eclipse 或任何 IDE),但会将 common-config jar 从可用于继承的依赖项中排除。在运行时,您将提供正确的文件(取决于 dev/test/prod 环境),如 Alex 所示。

于 2017-08-01T14:58:13.660 回答
0

就我而言,我修改了斯蒂芬的答案,project.clj看起来像这样:

:profiles {:dev {:resource-paths ["test/resources"]}}  ; appended to default

并且新目录test/resources包含logback.xml用于测试库的目录,但不会传播给该库的用户。

请注意,根据注释,"test/resources"附加到默认值:resources-paths以创建最终值["resources" "test/resources"]

于 2019-08-28T17:45:02.857 回答