Java material that occurs on a regular basis. It was decided to output a certain information as a log, but as a result of considering whether to output it to a database or a file, I decided to output a log to a file, so a memo when considering in advance. The premise is Linux.
The viewpoints are completely different, but enumerate as you can think of
--Since the storage area overhead is smaller than that of the database, it does not consume space. --When the log becomes large, it is necessary to consider dividing the data, but in the case of a database, it is troublesome to implement the process of creating a table, but if it is a file, the program only creates a new file. Easy --When you refer to the log, you cannot see it unless you log in and hit SQL if it is a database, but if it is a file, you can easily refer to it with more / less. --In the case of a database, it is necessary to additionally consider the effect on the backup of the database (processing time, etc.), but in the case of a file, only the backup of the entire system needs to be considered.
--If the exclusive processing is not performed properly, the file may be corrupted. --When searching, it is necessary to devise to improve performance because there is no index. --When performing a search, you need to create your own search logic because SQL cannot be used.
So I made a program that outputs a one-line log consisting of time and text to a file. The file is generated monthly. It seems easy to use the synchronized method as exclusive control, so I chose this method. Of course, it is a major premise that you do not operate the log file other than this method.
LogWriter.java
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.io.*;
public class LogWriterNew{
public static SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");
public static synchronized void writeLog(String text){
Calendar calendar = Calendar.getInstance();
String OUTPUT_DIR= "out";
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
Date date = calendar.getTime();
String yearStr = String.format("%04d", year);
String monthStr = String.format("%02d", month);
//Log output
String file_name = OUTPUT_DIR + File.separator + yearStr + "_" + monthStr + ".log";
File file = new File(file_name);
FileWriter fw = null;
String line = sdf.format(date) + "," + text;
try{
fw = new FileWriter(file, true);
fw.write(line + "\n");
}catch(IOException e){
e.printStackTrace();
}finally {
if(fw != null) {
try {
fw.close();
}catch(Exception e2) {
e2.printStackTrace();
}
}
}
}
public static void main(String[] argv){
for(int i=0; i<1000;i++){
System.out.println(i);
writeLog(i + "aaa");
}
}
}
Like this.
2020/05/23 08:25:02,0aaa
2020/05/23 08:25:02,1aaa
2020/05/23 08:25:02,2aaa
2020/05/23 08:25:02,3aaa
2020/05/23 08:25:02,4aaa
2020/05/23 08:25:02,5aaa
2020/05/23 08:25:02,6aaa
2020/05/23 08:25:02,7aaa
2020/05/23 08:25:02,8aaa
2020/05/23 08:25:02,9aaa
2020/05/23 08:25:02,10aaa
・ ・ ・ ・
On a small PC, we got a throughput of ``` 850 cases / sec` ``.
Since the character code cannot be specified with FileWriter, I tried to specify the character code using OutputStreamWriter.
//Log output method
public static synchronized boolean writeLog(String fileName, String date, String[] items){
for(int i=0; i<items.length; i++){
items[i] = escape(items[i]);
}
String line = date + "," + String.join(",", items);
File file = new File(fileName);
PrintWriter pw = null;
try {
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "Windows-31j")));
pw.println(line);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (pw != null) {
try {
pw.close();
} catch (Exception e2) {
e2.printStackTrace();
return false;
}
}
}
Next time, I will verify whether exclusive control is really done by this syncronized.
Recommended Posts