带有通配符的Logback记录器名称

时间:2018-02-07 06:10:01

标签: logging logback

是否可以使用通配符作为匹配不同包的记录器名称,因此我们不必单独指定它们?所以不要写

<logger name="com.package1.web" level="debug"   
<logger name="com.package2.web" level="debug"  
<logger name="com.package3.web" level="debug"  

我只想指定一个类似这样的条目:

<logger name="com.*.web" level="debug"  

如果有人知道某种方式,或者只是因为它不可能我非常欣赏它

2 个答案:

答案 0 :(得分:6)

您可以使用appender中的过滤器执行此操作。基本上你必须为DEBUG级别的“com。*”设置一个记录器,并应用一个DENY所有DEBUG(或爱人)事件的过滤器,这些事件不是“com。*。web”。

我承认这很复杂。

性能方面它也很差:为所有“com。*”事件创建调试事件,并且只在它们被丢弃或保留的appender上创建。

无论如何,例如logback.xml:

public class ButtonSharingFragment extends Fragment implements UpdateColorCallback {

    RecyclerView recyclerView;

    Button publicContacts;
    Button phoneContacts;
    Button justMeContacts;

    // ArrayList called selectPhoneContacts that will contain SelectPhoneContact info
    ArrayList<SelectPhoneContact> selectPhoneContacts;

    // The onCreateView method is called when Fragment should create its View object hierarchy,
    // either dynamically or via XML layout inflation.
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {

        PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, getActivity());

         adapter.setUpdateListener(this);

        View buttonView = inflater.inflate(R.layout.sharing_buttons, parent, false);
        //return inflater.inflate(R.layout.sharing_buttons, parent, false);


        //for the Public, phoneContacts, justMe, save and cancel buttons
        publicContacts = (Button) buttonView.findViewById(R.id.btnPublic);
        phoneContacts = (Button) buttonView.findViewById(R.id.btnPhoneContacts);
        justMeContacts = (Button) buttonView.findViewById(R.id.btnJustMe);



        // Defines the xml file for the fragment
        return buttonView;
    }




    @Override
    public void onUpdateColorCallback() {
        // TODO: Implement this
        //Toast.makeText(getActivity(), "yes, this is working now"", Toast.LENGTH_SHORT).show();
        Log.i("MyMessage","yes, this is working now");
    }
}

测试代码:

<configuration scan="true" debug="true">
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
            <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
                <expression>
                    !(e.loggerName ==~ "com\\..*\\.web") &amp;&amp;
                    DEBUG.toInt() >= e.level.toInt()
                </expression>
            </evaluator>
            <OnMismatch>NEUTRAL</OnMismatch>
            <OnMatch>DENY</OnMatch>
        </filter>
        <encoder>
            <pattern>%p [%d{HH:mm:ss,SSS}] %c - %m\n</pattern>
        </encoder>
    </appender>

    <logger name="com" level="DEBUG" />

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

结果:

public void test() throws Exception{
    getLogger("com.package1.web").debug("some debug onto com.package1.web");
    getLogger("com.package2.web").debug("some debug onto com.package2.web");
    getLogger("com.package3.web").debug("some debug onto com.package3.web");
    getLogger("com.package1.web").info("some info onto com.package1.web");
    getLogger("com.package2.web").info("some info onto com.package2.web");
    getLogger("com.package3.web").info("some info onto com.package3.web");
    getLogger("com.package3.notweb").debug("some debug onto com.package3.notweb");
    getLogger("com.package3.notweb").info("some info onto com.package3.notweb");
}

public Logger getLogger(String loggerName) {
    return LoggerFactory.getLogger(loggerName);
}

如您所见,调试日志仅针对“com。*。web”

编写

答案 1 :(得分:3)

TL; DR

Logback不支持记录器名称中间级别的通配符。

详细

Logback(隐式)支持记录器名称末尾的通配符,因此<logger name="com.package1.web" ...>实际上意味着:

  • com.package1.web
  • 的任何子包中的com.package1.web 中的类

Logback通过创建记录器层次结构来实现此目的; com.package1.web的记录器由com.package1的记录器作为父级,该记录器由com的记录器作为父级由ROOT记录器构成。

因此,如果您声明<logger name="com.package1.web" level="debug">,然后尝试为com.package1.web.foo.bar上的记录器发出调试日志消息,Logback将走向该记录器的层次结构,直到它找到一个记录器, DEBUG级别已启用,它将在com.package1.web找到,因此它将发出DEBUG日志事件。

但是,Logback不会根据记录器名称中间级别的wilcard创建层次结构。所以,这......

<logger name="com.*.web" level="debug">

...不会导致Logback为:

创建记录器
  • com.package1.web
  • com.package2.web
  • com.package3.web

当记录器名称中的中间级别显示通配符时,不会应用Logback的层次结构行为。

可能的解决方案

此层次结构行为的一个好处是,它允许您将记录器配置应用于包以及该包下的所有类,即它根据其父项在记录器实例之间创建关联。您可以通过提供显式记录器名称来进行此关联,而不是将其默认为当前类名。

例如:

<logger name="DEBUG_LOGGER" level="debug">

然后,您想要使用调试记录器的任何地方只需创建一个Logger实例,如下所示:

private final Logger logger = LoggerFactory.getLogger("DEBUG_LOGGER");

显然,这种方法也存在缺陷,我在这里只是提到它,表明还有另一种方法(除了完全限定的类名)来关联记录器实例并对它们应用一个级别。