Wednesday, September 21, 2011

Simple program to tail a log file

Recently I came across a requirement to develop a a logging program that tails the log file, similar to a tail log program. I need to tail the specific number of lines of a log file. After some research I decided to go with RandomAccessFile method of getting the check the last number of lines. Then I need something to keep on reading the log file and print it out. Try to use RandomAccessFile but it keeps locking the log file and unable to read it in real time. Then I try the BufferedReader with threading approach although the end result of printing out the output is there will be an extra new line as it prints out the values in the console.
Tried to resolve this extra new line but can't find any solution to it. Anyway the code is as below.


public class Tailog implements Runnable {
boolean execute = true;
BufferedInputStream reader;
BufferedReader in;
File file;
RandomAccessFile raf;
InputStreamReader inputStreamReader;
BufferedReader bufferedReader;
PrintWriter pwriter;
public Tailog() {
}
public Tailog(long numLine, String fileName, PrintWriter pw) {
try {
file = new File(fileName);
try {
//get last n lines
raf = new RandomAccessFile(file, "rw");
List<Long> seekPosi = new ArrayList<Long>();
long fileLength = file.length();
long tailrow = 0;
for (long i = fileLength - 2; i >= 0; i--) {
raf.seek(i);
String readLine = raf.readLine();


if (readLine.equals("")) {
seekPosi.add(i - 1);
tailrow++;
i--;
}
if (tailrow == numLine)
break;
}


Collections.sort(seekPosi);
for (long x : seekPosi) {
raf.seek(x + 2);
String printLine = raf.readLine();
pw.println(printLine);


}
raf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}


// start read line by line
inputStreamReader = new InputStreamReader(new FileInputStream(
fileName));
bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine();
while (line != null) {
line = bufferedReader.readLine();
}
pwriter = pw;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}


public void run() {
while (execute) {
try {
String line = bufferedReader.readLine();
if (line != null) {
pwriter.println(line);
pwriter.flush();
} else {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
execute = false;
}
}


} catch (Exception e) {
e.printStackTrace();
}
}
}


public static void main(String[] args) throws Exception {
PrintWriter pw = new PrintWriter(System.out, true);
String numLineStr = "";
String fileName = "";
try {
numLineStr = args[0];
fileName = args[1];
} catch (Exception e) {
e.printStackTrace();
}

long numLine = 0;
try {
numLine = Long.parseLong(numLineStr);
File file = new File(fileName);
if(file.exists()){
Tailog tailog = new Tailog(numLine, fileName, pw);
tailog.run();
}
else{
pw.println("Please specify correct file name: eg C:/server/log/server.log");
}
} catch (Exception e) {
e.printStackTrace();
pw.println("Please specify correct command: java -jar Tailog.jar <number of lines> <file name>");
}
}
}

Monday, September 12, 2011

Html 5 upload and display image on canvas - Firefox and Chrome

Tried html5 to upload and display image on canvas. Mostly example only works on Firefox. After looking around tried the FileReader method. Both Firefox and Chrome supports the FileReader object. IE still not supporting this object at the moment. Maybe in the next IE version. Anyway below is the javascript to upload and display image on canvas. Tested on jboss 7 server. Won't work if not run on server though.




<script>
function handleFileSelect(files) {


for ( var i = 0, f; f = files[i]; i++) {


// Only process image files.
if (!f.type.match('image.*')) {
continue;
}


var reader = new FileReader();


// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
var img = document.createElement("img");
img.src = e.target.result;
img.onload = function() {
var canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
context.drawImage(img, 0, 0);


}
};
})(f);


// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
</script>



<body>
       <input type="file" id="files" name="files[]" multiple onchange="handleFileSelect(this.files)"/>
       <canvas id="myCanvas" width="778" height="600"></canvas>  
</body>



Tuesday, September 6, 2011

Getting data from json format using json tokener

I was asked to use extJs grid to display some info on the data grid component. Fine but the component uses json format to display its data on the grid. So deleting data from the grid need to pass in data as json format. Anyway here is the method to retrieve the id from the json data to perform deletion in the grid using JsonTokener. Need to download the net.sf.json jar files from the json website.

import net.sf.json.JSONArray;import net.sf.json.util.JSONTokener;   
public String delJson(String delData, int total, int start){
        ProjectService projService = (ProjectService) SpringApplicationContext.getBean("projectService");
         
        String returnJson = "";
        String delId = "";
        try {
            JSONArray ja = new JSONArray();
            ja = JSONArray.fromObject(delData);
            int jsize = ja.size();
            
            while(jsize!=0){
                String jstr = ja.getString(jsize - 1);
                JSONTokener jt = new JSONTokener(jstr);
                jt.skipPast("id\":");
                delId = jt.nextValue().toString();
                
                if(delId!=null && !"".equals(delId)){
                    try {
                        
                        projService.delete(delId);
                    } catch (NumberFormatException e) {
                        
                        logger.error("error ProjectBean.delJson",e);
                    } catch (Exception e) {
                        
                        logger.error("error ProjectBean.delJson",e);
                    }
                }
                jsize--;
            }
            
        } catch (Exception e) {
            
            logger.error("error ProjectBean.delJson",e);
        }
        return returnJson;
    }