I want to create a custom logger for android application. The logging should be done in a separate thread as the application generates lots of information. I don't want to use the Android logs since i need to write the logs in a specific format. Multiple threads will be writing to the log file at the same time, so i have used a queue to keep the log messages
Here is the code that i have
Queue<LogEntry> logQueue = new LinkedBlockingQueue<LogEntry>();
LogWritterThread logWritterThread = new LogWritterThread();
// to queue the log messages
public void QueueLogEntry(String message)
{
    LogEntry le = new LogEntry(message);
    {
        logQueue.add(le);
        logQueue.notifyAll();
    }
logWritterThread.start();
}
    class LogWritterThread extends Thread 
{
    public void run() 
    {
        try 
        {
            while(true)
            {
                //thread waits until there are any logs to write in the queue
                if(logQueue.peek() == null)
                    synchronized(logQueue){
                        logQueue.wait();
                    }
                if(logQueue.peek() != null)
                {
                    LogEntry logEntry;
                    synchronized(logQueue){
                        logEntry = logQueue.poll();
                    }
                    // write the message to file
                }
                if(Thread.interrupted())
                    break;
            }
        } 
        catch (InterruptedException e) 
        {                
        }
    }
}
Is there any thing wrong with this code? or a better way to create a logging queue
Thanks, Anuj
Java BlockingQueue implementations already have synchronization concerns built in. Your use of wait, notify, and synchronized is redundant and not needed.
Try mimicking the Producer/Consumer example giving in the BlockingQueue javadoc
class LogEntry {
  private final String message;
  LogEntry(String msg) {
    message = msg;
  }
}
class LogProducer {
   private final BlockingQueue<LogEntry> queue;
   LogProducer(BlockingQueue<LogEntry> q) {
     queue = q;
   }
   public void log(String msg) {
      queue.put(new LogEntry(msg));
   }
 }
class LogConsumer implements Runnable {
   private final BlockingQueue<LogEntry> queue;
   LogConsumer(BlockingQueue<LogEntry> q) {
     queue = q;
   }
   public void run() {
     try {
       while(true) {
         LogEntry entry = queue.take();
         // do something with entry
       }
     } catch(InterruptedException ex) {
       // handle
     }
   }
}
class Setup {
  public static void main(String[] args) {
    BlockingQueue<LogEntry> queue = new LinkedBlockingQueue<LogEntry>();
    LogConsumer c = new LogConsumer(queue);
    new Thread(c).start();
    LogProducer p = new LogProducer(queue);
    p.log("asynch");
    p.log("logging");
  }
}
                        I would use a Handler - I love handler's because they implement a queue and a message thread all of which is thread safe. That means you can create a class that extends a Handler and use that class all over your project. With a couple of lines of code with a handler, you can shrink your existing code dramatically.
Google's documentation: http://developer.android.com/reference/android/os/Handler.html
This is a very simple example: http://saigeethamn.blogspot.com/2010/04/threads-and-handlers-android-developer.html
this is a better example because they use "msg.what" to decide what to do (which you'll need for different levels of logging): https://idlesun.wordpress.com/2010/12/12/android-handler-and-message-tutorial/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With