- Set android log tag to "I2P"

- Log to console buffer too
- New log activity
- Debug status output when router not running
- More logging utility methods
This commit is contained in:
zzz
2011-06-24 03:23:19 +00:00
parent 1aa08d8341
commit cadb6e8c1e
10 changed files with 248 additions and 33 deletions

View File

@ -50,5 +50,9 @@
android:label="Address Book"
android.theme="@android:style/Theme.NoTitleBar" >
</activity>
<activity android:name=".activity.LogActivity"
android:label="Logs"
android.theme="@android:style/Theme.NoTitleBar" >
</activity>
</application>
</manifest>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:textSize="18sp"
android:text="Logs" >
</TextView>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="6dp"
android:textSize="16sp" >
</TextView>

View File

@ -69,6 +69,18 @@
android:layout_height="wrap_content"
android:text="Address Book"
/>
<Button
android:id="@+id/logs_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Logs"
/>
<Button
android:id="@+id/error_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Error Logs"
/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"

View File

@ -1,3 +1,4 @@
logger.consoleBufferSize=250
logger.dateFormat=MM/dd HH:mm:ss.SSS
logger.defaultLevel=INFO
logger.displayOnScreen=true

View File

@ -0,0 +1,70 @@
package net.i2p.android.router.activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.android.router.R;
public class LogActivity extends ListActivity {
boolean errorsOnly;
final static String ERRORS_ONLY = "errors_only";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Grab context if router has started, otherwise create new
// FIXME dup contexts, locking, ...
List<String> msgs;
String header;
I2PAppContext ctx = I2PAppContext.getCurrentContext();
if (ctx != null) {
Intent intent = getIntent();
errorsOnly = intent.getBooleanExtra(ERRORS_ONLY, false);
if (errorsOnly) {
msgs = ctx.logManager().getBuffer().getMostRecentCriticalMessages();
} else {
msgs = ctx.logManager().getBuffer().getMostRecentMessages();
}
int sz = msgs.size();
if (sz == 0) {
header = "No messages";
} else if (sz == 1) {
header = "1 message";
} else {
header = sz + " messages, newest first";
Collections.reverse(msgs);
}
} else {
msgs = Collections.EMPTY_LIST;
header = "No messages";
}
// set the header
TextView tv = (TextView) getLayoutInflater().inflate(R.layout.logs_header, null);
tv.setText(header);
ListView lv = getListView();
lv.addHeaderView(tv, "", false);
setListAdapter(new ArrayAdapter<String>(this, R.layout.logs_list_item, msgs));
// set the callback
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View view, int pos, long id) {
// make it bigger or something
}
});
}
}

View File

@ -38,16 +38,16 @@ public class MainActivity extends I2PActivityBase {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button news = (Button) findViewById(R.id.news_button);
news.setOnClickListener(new View.OnClickListener() {
Button b = (Button) findViewById(R.id.news_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), NewsActivity.class);
startActivity(intent);
}
});
Button notes = (Button) findViewById(R.id.releasenotes_button);
notes.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.releasenotes_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), TextResourceActivity.class);
intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
@ -55,8 +55,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button licenses = (Button) findViewById(R.id.licenses_button);
licenses.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.licenses_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), LicenseActivity.class);
//Intent intent = new Intent(view.getContext(), TextResourceActivity.class);
@ -65,8 +65,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button website = (Button) findViewById(R.id.website_button);
website.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.website_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), WebActivity.class);
//intent.setData((new Uri.Builder()).scheme("http").authority("www.i2p2.de").path("/").build());
@ -75,8 +75,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button faq = (Button) findViewById(R.id.faq_button);
faq.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.faq_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), WebActivity.class);
//intent.setData((new Uri.Builder()).scheme("http").authority("www.i2p2.de").path("/faq").build());
@ -85,8 +85,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button welcome = (Button) findViewById(R.id.welcome_button);
welcome.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.welcome_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), WebActivity.class);
// default is to display the welcome_html resource
@ -94,16 +94,33 @@ public class MainActivity extends I2PActivityBase {
}
});
Button addressbook = (Button) findViewById(R.id.addressbook_button);
addressbook.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.addressbook_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), AddressbookActivity.class);
startActivity(intent);
}
});
Button start = (Button) findViewById(R.id.router_start_button);
start.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.logs_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), LogActivity.class);
startActivity(intent);
}
});
b = (Button) findViewById(R.id.error_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), LogActivity.class);
intent.putExtra(LogActivity.ERRORS_ONLY, true);
startActivity(intent);
}
});
b = (Button) findViewById(R.id.router_start_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
RouterService svc = _routerService;
if (svc != null && _isBound) {
@ -116,8 +133,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button stop = (Button) findViewById(R.id.router_stop_button);
stop.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.router_stop_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
RouterService svc = _routerService;
if (svc != null && _isBound) {
@ -128,8 +145,8 @@ public class MainActivity extends I2PActivityBase {
}
});
Button quit = (Button) findViewById(R.id.router_quit_button);
quit.setOnClickListener(new View.OnClickListener() {
b = (Button) findViewById(R.id.router_quit_button);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
RouterService svc = _routerService;
if (svc != null && _isBound) {
@ -157,6 +174,7 @@ public class MainActivity extends I2PActivityBase {
{
super.onStart();
_handler.removeCallbacks(_updater);
_handler.removeCallbacks(_oneShotUpdate);
if (_savedStatus != null) {
TextView tv = (TextView) findViewById(R.id.main_status_text);
tv.setText(_savedStatus);
@ -170,6 +188,7 @@ public class MainActivity extends I2PActivityBase {
{
super.onStop();
_handler.removeCallbacks(_updater);
_handler.removeCallbacks(_oneShotUpdate);
}
@Override
@ -227,10 +246,11 @@ public class MainActivity extends I2PActivityBase {
private void updateStatus() {
RouterContext ctx = getRouterContext();
TextView tv = (TextView) findViewById(R.id.main_status_text);
/***
if (!Util.isConnected(this)) {
tv.setText("No Internet connection is available");
tv.setVisibility(View.VISIBLE);
} else if (ctx != null) {
} else ****/ if (ctx != null) {
int active = ctx.commSystem().countActivePeers();
int known = Math.max(ctx.netDb().getKnownRouters() - 1, 0);
int inEx = ctx.tunnelManager().getFreeTunnelCount();
@ -273,7 +293,18 @@ public class MainActivity extends I2PActivityBase {
tv.setText(_savedStatus);
tv.setVisibility(View.VISIBLE);
} else {
tv.setVisibility(View.INVISIBLE);
//tv.setVisibility(View.INVISIBLE);
RouterService svc = _routerService;
String status =
"connected? " + Util.isConnected(this) +
"\nhave ctx? " + (ctx != null) +
"\nhave svc? " + (svc != null) +
"\nis bound? " + _isBound +
"\nsvc state: " + (svc == null ? "null" : svc.getState()) +
"\ncan start? " + (svc == null ? "null" : svc.canManualStart()) +
"\ncan stop? " + (svc == null ? "null" : svc.canManualStop());
tv.setText(status);
tv.setVisibility(View.VISIBLE);
}
}

View File

@ -27,7 +27,7 @@ import net.i2p.util.NativeBigInteger;
* Runs the router
*/
public class RouterService extends Service {
private enum State {INIT, WAITING, STARTING, RUNNING,
public enum State {INIT, WAITING, STARTING, RUNNING,
// unplanned (router stopped itself), next: killSelf()
STOPPING, STOPPED,
// button, don't kill service when stopped, stay in MANUAL_STOPPED
@ -218,6 +218,11 @@ public class RouterService extends Service {
return rv;
}
/** debug */
public String getState() {
return _state.toString();
}
public boolean canManualStop() {
return _state == State.WAITING || _state == State.STARTING || _state == State.RUNNING;
}

View File

@ -7,6 +7,9 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
public abstract class Util {
private static final boolean _isEmulator = Build.MODEL.equals("sdk");
@ -39,4 +42,64 @@ public abstract class Util {
return current;
}
private static final String ANDROID_TAG = "I2P";
public static void e(String m) {
e(m, null);
}
/**
* Log to the context logger if available (which goes to the console buffer
* and to logcat), else just to logcat.
*/
public static void e(String m, Throwable t) {
I2PAppContext ctx = I2PAppContext.getCurrentContext();
if (ctx != null)
ctx.logManager().getLog(Util.class).log(Log.ERROR, m, t);
else if (t != null)
android.util.Log.e(ANDROID_TAG, m + ' ' + t + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.e(ANDROID_TAG, m);
}
public static void w(String m) {
w(m, null);
}
public static void w(String m, Throwable t) {
I2PAppContext ctx = I2PAppContext.getCurrentContext();
if (ctx != null)
ctx.logManager().getLog(Util.class).log(Log.WARN, m, t);
else if (t != null)
android.util.Log.w(ANDROID_TAG, m + ' ' + t + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.w(ANDROID_TAG, m);
}
public static void i(String m) {
i(m, null);
}
public static void i(String m, Throwable t) {
I2PAppContext ctx = I2PAppContext.getCurrentContext();
if (ctx != null)
ctx.logManager().getLog(Util.class).log(Log.INFO, m, t);
else if (t != null)
android.util.Log.i(ANDROID_TAG, m + ' ' + t + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.i(ANDROID_TAG, m);
}
public static void d(String m) {
d(m, null);
}
public static void d(String m, Throwable t) {
I2PAppContext ctx = I2PAppContext.getCurrentContext();
if (ctx != null)
ctx.logManager().getLog(Util.class).log(Log.DEBUG, m, t);
else if (t != null)
android.util.Log.d(ANDROID_TAG, m + ' ' + t + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.d(ANDROID_TAG, m);
}
}

View File

@ -105,6 +105,12 @@ class LogWriter implements Runnable {
else
log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage(), rec.getThrowable());
// to be viewed on android screen
String val = LogRecordFormatter.formatRecord(_manager, rec, true);
_manager.getBuffer().add(val);
if (rec.getPriority() >= Log.ERROR)
_manager.getBuffer().addCritical(val);
// we always add to the console buffer, but only sometimes write to stdout
if (_manager.getDisplayOnScreenLevel() <= rec.getPriority()) {
if (_manager.displayOnScreen()) {
@ -114,6 +120,8 @@ class LogWriter implements Runnable {
}
}
private static final String ANDROID_LOG_TAG = "I2P";
public void log(int priority, Class src, String name, String threadName, String msg) {
if (src != null) {
String tag = src.getName();
@ -121,15 +129,18 @@ class LogWriter implements Runnable {
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
tag,
'[' + threadName + "] " + msg);
ANDROID_LOG_TAG,
tag +
" [" + threadName + "] " + msg);
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
'[' + threadName + "] " + msg);
ANDROID_LOG_TAG,
name +
" [" + threadName + "] " + msg);
else
android.util.Log.println(toAndroidLevel(priority),
threadName, msg);
ANDROID_LOG_TAG,
'[' + threadName + "] " + msg);
}
public void log(int priority, Class src, String name, String threadName, String msg, Throwable t) {
@ -139,17 +150,20 @@ class LogWriter implements Runnable {
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
tag,
'[' + threadName + "] " + msg +
ANDROID_LOG_TAG,
tag +
" [" + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
'[' + threadName + "] " + msg +
ANDROID_LOG_TAG,
name +
" [" + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.println(toAndroidLevel(priority),
threadName,
ANDROID_LOG_TAG,
'[' + threadName + "] " +
msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
}