logback--How do I configure an AsyncAppender with code? 转载

原文地址:https://github.com/tony19/logback-android/issues/54

Please provide an example of how to configure the AsyncAppender with a FileAppender to write to the file in an async way. I am getting many StrictMode policy violations (StrictModeDiskWriteViolation) on every log write to my log file.

Thanks.

I verified the following config works in Android 4.2.2 without any exceptions.

<configuration debug="true">
  <property name="LOG_DIR" value="/data/data/com.example/files" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${LOG_DIR}/log.txt</file>
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE" />
  </appender>

  <root level="DEBUG">
    <appender-ref ref="ASYNC" />
  </root>
</configuration>

Example: Configure by in-memory XML string

package com.example;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    configureLogbackByString();

    org.slf4j.Logger log = LoggerFactory.getLogger(MainActivity.class);
    log.info("hello world!!");
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();

    // Assume SLF4J is bound to logback-classic in the current environment.
    // This must be called to properly shutdown AsyncAppender and flush logs
    // upon application exit.
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    loggerContext.stop();
  }

  String LOGBACK_XML =
      "<configuration debug=‘true‘>" +
          "  <property name=‘LOG_DIR‘ value=‘/data/data/com.example/files‘ />" +
          "  <appender name=‘FILE‘ class=‘ch.qos.logback.core.FileAppender‘>" +
          "    <file>${LOG_DIR}/log.txt</file>" +
          "    <encoder>" +
          "      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>" +
          "    </encoder>" +
          "  </appender>" +
          "  <appender name=‘ASYNC‘ class=‘ch.qos.logback.classic.AsyncAppender‘>" +
          "    <appender-ref ref=‘FILE‘ />" +
          "  </appender>" +
          "  <root level=‘DEBUG‘>" +
          "    <appender-ref ref=‘ASYNC‘ />" +
          "  </root>" +
          "</configuration>";

  private void configureLogbackByString() {
    // reset the default context (which may already have been initialized)
    // since we want to reconfigure it
    LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
    lc.reset();

    JoranConfigurator config = new JoranConfigurator();
    config.setContext(lc);

    InputStream stream = new ByteArrayInputStream(LOGBACK_XML.getBytes());
    try {
      config.doConfigure(stream);
    } catch (JoranException e) {
      e.printStackTrace();
    }
  }
}

Example: Configure with direct calls into logback

package com.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.util.StatusPrinter;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    configureLogbackDirectly();

    org.slf4j.Logger log = LoggerFactory.getLogger(MainActivity.class);
    log.info("hello world!!");

  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();

    // assume SLF4J is bound to logback-classic in the current environment
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    loggerContext.stop();
  }

  private void configureLogbackDirectly() {
    // reset the default context (which may already have been initialized)
    // since we want to reconfigure it
    LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
    lc.reset();

    // setup FileAppender
    PatternLayoutEncoder encoder1 = new PatternLayoutEncoder();
    encoder1.setContext(lc);
    encoder1.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n");
    encoder1.start();

    FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
    fileAppender.setContext(lc);
    fileAppender.setName("FILE");
    fileAppender.setFile(this.getFileStreamPath("log.txt").getAbsolutePath());
    fileAppender.setEncoder(encoder1);
    fileAppender.start();

    AsyncAppender asyncAppender = new AsyncAppender();
    asyncAppender.setContext(lc);
    asyncAppender.setName("ASYNC");

    // UNCOMMENT TO TWEAK OPTIONAL SETTINGS
//    // excluding caller data (used for stack traces) improves appender‘s performance
//    asyncAppender.setIncludeCallerData(false);
//    // set threshold to 0 to disable discarding and keep all events
//    asyncAppender.setDiscardingThreshold(0);
//    asyncAppender.setQueueSize(256);

    asyncAppender.addAppender(fileAppender);
    asyncAppender.start();

    // add the newly created appenders to the root logger;
    // qualify Logger to disambiguate from org.slf4j.Logger
    ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    root.addAppender(asyncAppender);

    StatusPrinter.print(lc);
  }
}
时间: 2024-10-20 10:06:58

logback--How do I configure an AsyncAppender with code? 转载的相关文章

读logback源码系列文章(五)——Appender --转载

原文地址:http://kyfxbl.iteye.com/blog/1173788 明天要带老婆出国旅游几天,所以这段时间暂时都更新不了博客了,临走前再最后发一贴 上一篇我们说到Logger类的info()方法通过层层调用,最后委托Appender来记录日志,这篇博客我们就接着说一下,Appender组件是怎么记录日志的 实际上Appender可能是logback框架中最重要的组件之一,虽然Logger是记录日志的接口,但是如果一个Logger没有关联到任何Appender的话,那么这个Logg

Java日志框架:logback详解

为什么使用logback 记得前几年工作的时候,公司使用的日志框架还是log4j,大约从16年中到现在,不管是我参与的别人已经搭建好的项目还是我自己主导的项目,日志框架基本都换成了logback,总结一下,logback大约有以下的一些优点: 内核重写.测试充分.初始化内存加载更小,这一切让logback性能和log4j相比有诸多倍的提升 logback非常自然地直接实现了slf4j,这个严格来说算不上优点,只是这样,再理解slf4j的前提下会很容易理解logback,也同时很容易用其他日志框架

logback的加载过程

使用logback-classic.jar时,启动应用后,logback按照以下顺序进行扫描: 1.在系统配置文件System Properties中寻找是否有logback.configurationFile对应的value 2.在classpath下寻找是是否有logback.groovy(即logback支持groovy与xml两种配置方式) 3.1.在classpath下寻找是否有logback-test.xml 3.2.在classpath下寻找是否有logback.xml 4.当找到

SLF4J和Logback日志框架详解

SLF4J和Logback日志框架详解 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 本文讲述SLF4J和Logback日志框架.   SLF4J是一套简单的日志外观模式的Java API,帮助在项目部署时对接各种日志实现. LogBack在运行时使用JMX帮助修改日志配置,在生产状态下无需重启应用程序. SLF4J SLF4J是简单的日志外观模式框架,抽象了各种日志框架例如Logback.Log4j.Commons-logging和JDK自带的l

【转】Arduino 控制USB设备(5)解析USB键盘的例子

下面是一个获得 USB 键盘数据的例子[参考1].原理上说,是将键盘切换为 Boot Protocol 这样就避免了需要具体解析HID的麻烦. 001 /* MAX3421E USB Host controller LCD/keyboard demonstration */ 002 //#include <Spi.h> 003 #include "Max3421e.h" 004 #include "Usb.h" 005   006 /* keyboard

Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

Intellij IDEA 14 作为Java IDE 神器,接触后发现,非常好用,对它爱不释手,打算离开eclipse和myeclipse,投入Intellij IDEA的怀抱. 然而在使用的过程中会发现Intellij IDEA也有一些不尽如意的地方,难免会有些不爽:Intellij IDEA 的插件库远不及eclipse的丰富. mybatis-generator在eclipse中有专门的插件,而没有开发出Intellij IDEA能够使用的插件. 不过不用灰心,如果你的项目是使用mave

博客园设置类似sublime高亮代码

需要用到highlight.js,需要FQ,官网为https://highlightjs.org,首先官网的只有默认主题包,我们需要自定义主题包需要去它的github上找,地址为https://github.com/isagalaev/highlight.js,我用的主题是monokai-sublime.css 所以呢在github上把这个css文件给copy下来,然后把它的js文件也copy下来.上传文件到博客园,不要用官网的cdn,因为样式不能自定义,还要担心哪天地址不能用了 <link r

Mybatis Generator insert useGeneratedKeys keyProperty

Mybatis自动生成代码,需要用到mybatis Generator,详见http://mybatis.github.io/generator/configreference/generatedKey.html insert语句如果要返回自动生成的key值,一般会在insert里加入useGeneratedKeys属性,例如 <insert id="insert" parameterType="cn.ac.iscas.pebble.ufe.bean.Subtask&q

程序的记事本--log4net

你是否在遇到程序运行问题时经常百度?你是否在遇到运行错误时经常去询问别人?如果有那么是时候改变啦,对于一个Developer来说那是不专业的表现,专业的Developer都会首先查看程序的运行日志,先从日志下手,分析问题发生的原因,然后修复它.这里面最重要的就是日志,那么你也就会很好奇,这些日志是如何记录的呢,偷偷的告诉你通常使用的是日志管理框架.那么是不是也想在开发程序时开发出一个日志管理的模块呢,不用着急下面就来介绍下如何做日志管理. 就我所知现在日志管理框架有多种如 Enterprise.