How can I get programatically any single Log generated by my App? - java

Any Android App produces Logs in the LogCat, even those not generated by developer's source code via Log.d, Log.i, Log.w and Log.e etc. etc. etc.. Perhaps Google Developers has some "automagic" thing for this, I don't know about that...
The point is I remember, years ago, I could somehow extend the class Application, override one or several of it's methods, and then:
Add my own code to process any single Log object generated by my
App in the LogCat
Do whatever I wanted with them (getting the label and the description strings, and then send them via mail, Slack etc., basically)
And then, calling super on that method and let the system do with that Log whatever Application by default does with it...
or something like that... if I recall correctly, I could do this with any log in my app's namespace. Or maybe it was just the crash handler? I can't remember...
It's been so long since I accomplished that (several years already!), so I don't remember how could I do that anymore... I search the internet like crazy trying to recall, but I am struggling to find it again... :-S
// ...public?? oO
[¿¿??] class MyApp extends Application [...] {
// [...]
#Override
public void whateverMethodItWasIDontRemember(params) {
// My coding stuff for the error reports
/* magic :D */
sendTheLogsMyWay();
// I bet this is important
super.whateverMethodItWasIDontRemember(params);
}
// [...]
}
I am about to launch the first Beta version of a new app, so I want beta testers to have a reliable way to send me LogCat's feed if anything has to be reported due to crashes, unexpected behaviour etc.
I mean, it would be ridiculous having to fill with CustomLogs every inch of source code for the beta version, when, in most cases, default logs are more than enough to see why it crashed (errors), or what optimization problems (usually warnings) might the Beta Tester have... not to mention that, if I forget to monitor something this way, the ridiculously big effort to log every single line of my code would be useless... oO
// -__- Mmm... perhaps extending Log itself
// would be more elegant...
import android.util.Log
public final class CustomLog {
public static void d(String label, String msg) {
// AKA My code to handle it
packItForNextErrorReport(label, msg);
Log.d(label, msg);
}
/*
* ... and so on with Log.i, w and e.
* ...I think you get the idea
*/
}

Related

Handling non-fatal errors in Java

I've written a program to aid the user in configuring 'mechs for a game. I'm dealing with loading the user's saved data. This data can (and some times does) become partially corrupt (either due to bugs on my side or due to changes in the game data/rules from upstream).
I need to be able to handle this corruption and load as much as possible. To be more specific, the contents of the save file are syntactically correct but semantically corrupt. I can safely parse the file and drop whatever entries that are not semantically OK.
Currently my data parser will just show a modal dialog with an appropriate warning message. However displaying the warning is not the job of the parser and I'm looking for a way of passing this information to the caller.
Some code to show approximately what is going on (in reality there is a bit more going on than this, but this highlights the problem):
class Parser{
public void parse(XMLNode aNode){
...
if(corrupted) {
JOptionPane.showMessageDialog(null, "Corrupted data found",
"error!", JOptionPane.WARNING_MESSAGE);
// Keep calm and carry on
}
}
}
class UserData{
static UserData loadFromFile(File aFile){
UserData data = new UserData();
Parser parser = new Parser();
XMLDoc doc = fromXml(aFile);
for(XMLNode entry : doc.allEntries()){
data.append(parser.parse(entry));
}
return data;
}
}
The thing here is that bar an IOException or a syntax error in the XML, loadFromFile will always succeed in loading something and this is the wanted behavior. Somehow I just need to pass the information of what (if anything) went wrong to the caller. I could return a Pair<UserData,String> but this doesn't look very pretty. Throwing an exception will not work in this case obviously.
Does any one have any ideas on how to solve this?
Depending on what you are trying to represent, you can use a class, like SQLWarning from the java.sql package. When you have a java.sql.Statement and call executeQuery you get a java.sql.ResultSet and you can then call getWarnings on the result set directly, or even on the statement itself.
You can use an enum, like RefUpdate.Result, from the JGit project. When you have a org.eclipse.jgit.api.Git you can create a FetchCommand, which will provide you with a FetchResult, which will provide you with a collection of TrackingRefUpdates, which will each contain a RefUpdate.Result enum, which can be one of:
FAST_FORWARD
FORCED
IO_FAILURE
LOCK_FAILURE
NEW
NO_CHANGE
NOT_ATTEMPTED
REJECTED
REJECTED_CURRENT_BRANCH
RENAMED
In your case, you could even use a boolean flag:
class UserData {
public boolean isCorrupt();
}
But since you mentioned there is a bit more than that going on in reality, it really depends on your model of "corrupt". However, you will probably have more options if you have a UserDataReader that you can instantiate, instead of a static utility method.

My own Logging Handler for GAE/J (using appengine.api.log?)

I need to write my own logging handler on GAE/J. I have Android code that I'm trying to adapt such that it can be shared between GAE/J and Android. The GAE code I'm trying to write would allow the log statements in my existing code to work on GAE.
The docs say that I can just print to system.out and system.err, and it works, but badly. My logging shows up in the log viewer with too much extraneous text:
2013-03-08 19:37:11.355 [s~satethbreft22/1.365820955097965155].: [my_log_msg]
So, I started looking at the GAE log API. This looked hopeful initially: I can construct an AppLogLine and set the log records for a RequestLogs object.
However, there is no way to get the RequestLogs instance for the current request - the docs say so explicitly here:
Note: Currently, App Engine doesn't support the use of the request ID to directly look up the related logs.
I guess I could invent a new requestID and add log lines to that, but it is starting to look like this is just not meant to be?
Has anyone used this API to create their own log records, or otherwise managed to do their own logging to the log console.
Also, where can I find the source for GAE's java.util.logging? Is this public? I would like to see how that works if I can.
If what I'm trying to do is impossible then I will need to consider other options, e.g. writing my log output to a FusionTable.
I ended up just layering my logging code on top of GAE's java.util.logging. This feels non-optimal since it increases the complexity and overhead of my logging, but I guess this is what any 3rd logging framework for GAE must do (unless it is OK with the extra cruft that gets added when you just print to stdout).
Here is the crux of my code:
public int println(int priority, String msg) {
Throwable t = new Throwable();
StackTraceElement[] stackTrace = t.getStackTrace();
// Optional: translate from Android log levels to GAE log levels.
final Level[] levels = { Level.FINEST, Level.FINER, Level.FINE, Level.CONFIG,Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
Level level = levels[priority];
LogRecord lr = new LogRecord(level, msg);
if (stackTrace.length > 2) { // should always be true
lr.setSourceClassName(stackTrace[2].getClassName());
lr.setSourceMethodName(stackTrace[2].getMethodName());
}
log.log(lr);
return 0;
}
Note that I use a stack depth of 2, but that # will depend on the 'depth' of your logging code.
I hope that Google will eventually support getting the current com.google.appengine.api.log.RequestLogs instance and inserting our own AppLogLine instances into it. (The API's are actually there to do that, but they explicitly don't support it, as above.)

Java Reflection permission error

I'm trying to load a class via an URLClassLoader (well, it neither works with an normal class loader) and want them to not have any permission.
Therefore, i created my own security manager, which genereates a key on startup, which can only by requested once (in main thread).
The security manager has 2 lists, the applicationThread, which will be granted any right and the temporaryList, which will be granted one right just once (it's about the reflection).
As it is very hard to descripe, i decided to upload the whole thing: look at the link below
Ok, coming back: I created a WatchDog thread, which checks if the thread doesn't take too much time.
When i now start to instance two classes from an URLClassLoader, I call exactly 30 methods without getting any errors, but on the 31st call, it tries to check Permissions for the following but this is just happaning after the 30th call.
java.lang.RuntimePermission accessClassInPackage.sun.reflect),
Does anyone know what's going on there?
edit:
I had time to strip down the example.
http://myxcode.at/securitymanager.zip
I found out, that the SecurityManager is not asked synchronous. Just run this small piece of code and have a look at the red lines.
If the red lines come in the very first line, just run the program again, you will find out that it seems a little bit uncontrolled.
The problem more or less is, that i need the security manager to be synchronized.
Here is my output for those who cannot face the error(bug?)
http://pastebin.com/E9yLRLif
edit2: maybe its about the console? maybe the console is too slow?
For me the check occurs when i=15:
checkPermission ( (java.lang.RuntimePermission accessClassInPackage.sun.reflect) ) for Thread[main,5,main]
The reason for the delayed permission check is an inflationThreshold of the ReflectionFactory class which is used by the invoke method of NativeMethodAccessorImpl.java:
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException {
if (++numInvocations > ReflectionFactory.inflationThreshold()) {
MethodAccessorImpl acc = (MethodAccessorImpl) new MethodAccessorGenerator()
.generateMethod(method.getDeclaringClass(), method
.getName(), method.getParameterTypes(),
method.getReturnType(), method
.getExceptionTypes(), method
.getModifiers());
parent.setDelegate(acc);
}
return invoke0(method, obj, args);
}
To disable the delay you could use Reflection API :)
Field hack = Class.forName("sun.reflect.ReflectionFactory").getDeclaredField("inflationThreshold");
hack.setAccessible(true);
hack.set(null, 0);

Messaging between Java and Flex with Flerry

I'm currently working on a project that need to communicate with java from air without the use of a server like Tomcat. For this i found and use Flerry.
Communicating between Java and Air is no problem, as long as I try to send a message from the class that I initially instantiated from Air.
What I try to do is subscript to messages from a Message Class in java and use that class to send info and errors to Air from Java.
MessageController.java:
public class MessageController
{
public MessageController()
{
}
public static void sendErrorMessage(String errorMessage)
{
NativeObject.sendMessage(errorMessage, "error");
}
public static void sendInfoMessage(String infoMessage)
{
NativeObject.sendMessage(infoMessage, "info");
}
}
In Air I create a NativeObject on the messaging class and subscribe to the messages:
var messageController:NativeObject = new NativeObject();
messageController.source = "controller.MessageController" ;
messageController.singleton = true;
messageController.debug = false;
messageController.addEventListener(FaultEvent.FAULT, onFileControllerFault, false, 0, true);
messageController.subscribe("info", infoMessageHandler);
messageController.subscribe("error", errorMessageHandler);
As you would have guessed, this doesn't work.
It seems that I am only able to dispatch messages from the class that I subscribe to directly, for example if I do this:
messageController.start();
and in my MessageController.java i put this:
public void start()
{
NativeObject.sendMessage("test message", "info");
}
the infoMessageHandler receives an message containing test message, as it should.
How can I dispatch messages from whatever class in Java and catch them on the Air side?
I'm not sure I fully understand the issue yet, but is there a reason you can't simply send and receive all messages through a Java 'communication' class? If that's working, I'd just set up public methods in Java interfacing/communications class and be done with it.
(It's been awhile since I've dug into how Flerry works so I can't recall enough to point out the likely cause of the behavior you're seeing.) Also Flerry is open source, and not very big at all. If you really want to know why it's behaving in a certain way, I'd wager you could figure it out by looking at the source. (Won't take 6 months to learn like some Spring or Hibernate code base, or even BlazeDS, I promise.)
I do use Flerry in a small app, but now that I think about it, I only have one class which dispatches anything to Flex! But I feel like you may need to describe the problem you're facing differently, because it sounds like expected behavior to me.

JFreeChart Exceptionless Forever-blocking error

I am not sure if this is a permissions problem, or an error in JFreeChart (latest version 1.0.13) with my web application that is running on Tomcat in CentOS. But I have a very odd situation where I in my application an event fires, eventually causing the below method to be executed with the supplied parameters.
I've checked the documentation and it appears that these static methods don't throw exceptions, so I can only assume they return null series or similar if they cannot execute properly. However, in my case, I will execute the use case that causes this code to be run, and as I'm looking at the Tomcat log catalina.out, I can see the line "===================5" appear, but "===================6" never does. And that's where I am stumped. And clearly since "chart" never get's made, the image file can never be generated, leaving an ugly error on my webpage.
Can anyone shed some light on why ChartFactory.createTimeSeriesChart seems to hang? Wouldn't bad input cause the method to return a null series or something, certainly this very mature product wouldn't just sit there and block forever right?
The other detail is that this worked in the GWT servlet container, and also another Tomcat servlet container on Windows...which kind of makes me think there could be some permissions issue. Except that for my last test I made everything root...
Finally, perhaps I missed something huge and JFree methods do throw exceptions? Perhaps my catch block errors out and the message never goes to my error logs?
EDIT: The class files in my .war were compiled the Windows machine that they function correctly on. bytecode is bytecode, right? Or is there some potential problem?
EDIT 2: The project is headless and configured as such.
Code:
public LineChart(final String title, List<GraphData> graphxy[],
String url, String sensorName[], String unit[], float critHigh,
float critLow, Double percent, String historic, String clickZoomIn,
String BaseUrl,Date[][] dateDifference)
throws IOException
{
try {
...
System.out.println("===================5");
//All the parameters are built defined in excised code:
final JFreeChart chart = ChartFactory.createTimeSeriesChart(ShowsensorName, "Date", readUnit, dataset, true, true, false);
System.out.println("===================6");
...
}
catch (Exception e)
{
System.out.println("Exception in line chart demo is========="+e);
}
}
Here's a few things to try:
If headless, verify correct setup.
Try related demos on the affected server.
Try evoking your chart as an application, e.g. TimeSeriesChartDemo1.
Walk through the source by clicking the createTimeSeriesChart() link.

Categories

Resources