Comments (4)
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);
}
}
from logback-android.
I updated my comment above to include the logback function calls equivalent to the XML.
from logback-android.
Quick question about shutting down the AysncAppender
https://github.com/tony19/logback-android/wiki/Appender-Notes#asyncappender
I noticed you said you should call it on the onDestroy method. Would that mean for all the activities and services in live in the same application have this call below on all the onDestory methods?
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.stop();
Is this call even needed?
Dont' think can use the hook right?
from logback-android.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
from logback-android.
Related Issues (20)
- How to append Build Version Number with Log Main File HOT 1
- Document usage compatible with the standard JUnit tests
- write log after app killed ,how to write log real time HOT 1
- Log file is not creating at very first time when app gets launched in android. HOT 5
- No log is printed with Slf4j 2.x.x HOT 10
- Missing SSL parameter configuration HOT 1
- Dependency Dashboard
- how to rename locback.xml as logback-demo.xml HOT 1
- Caused by java.lang.NullPointerException Attempt to invoke interface method 'void androidx.appcompat.view.menu.d.u(int)' on a null object reference HOT 1
- ArrayIndexOutOfBoundsException on Android 10
- LogcatAppender show errors for logs' "highlighting".
- Lazy setting does not work
- Can't Create Logger: DateTokenConverter not found? HOT 2
- The log cannot be written correctly in the case of multi-process Android application? HOT 2
- Cannot create AAR with ./scripts/makejar.sh HOT 1
- Excepton in kotlin app with jetpack compose, only in release mode HOT 1
- Missing transitive dependency on slf4j-api-2.x
- The release version turns on minifyEnabled, and the file name is printed as null. <pattern>[%date] [%file:%line] - %msg%n</pattern>
- logback-android and logback-classic ILoggingEvent binary incompatibility getMarkers vs getMarkerList HOT 1
- can not write to the file that under the android getExternalFilesDir()
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from logback-android.