1
\$\begingroup\$

I'm using a simple logger on a server, which uses a method that looks like this:

@Override
public synchronized void write(String logtag, String reason, int severity) {

    long logtime = System.currentTimeMillis();
    String message = "";

    switch (severity) {
        case DEBUG:
            if (!debug) return;
            message = "[" + logtime + "] {DEBUG} " + logtag + "% " + reason + "\n$";
            break;
        case INFO:
            message = "[" + logtime + "] {INFO} " + logtag + "% " + reason + "\n$";
            break;
        case ERROR:
            message = "[" + logtime + "] {ERROR} " + logtag + "% " + reason + "\n$";
            break;
        case FATAL:
            message = "[" + logtime + "] {FATAL} " + logtag + "% " + reason + "\n$";
           break;
        case EXCEPTION:
            message = "[" + logtime + "] {EXCEPTION} " + logtag + "% " + reason + "\n$";
            break;
        default:
            message = "Anthrazit error! Invalid severity: " + severity;
    } 

    try {
        out.write(message.getBytes(StandardCharsets.UTF_8));
    } catch (IOException e) {
        errorOnInit(e);
    }

    if (exitOnFatal && severity == FATAL) {
        System.err.println("Anthrazit exit on fatal: " + message + ". Please check the logs.");
        close();
        System.exit(1);
    }

}

After doing some research I found some classes designed to to this, like PrintWriter and others. Is there any performance difference between my approach and the PrintWriters?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

According to its javadoc:

FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter.

See also: https://stackoverflow.com/questions/11371154/outputstreamwriter-vs-filewriter

You could also use a StringBuilder instead of doing manually a string concatenation.

Also, the whole method is sychronized. The message probably does not need to be constructed in the sychronized block. Only concrete write to the Stream/File should be sychronized:

long logtime = System.currentTimeMillis();
// construct string etc

sychronized(this){
    out.write(message.getBytes(StandardCharsets.UTF_8));
}

You could also try to read the code of "real" logging frameworks to get ideas how they work.

\$\endgroup\$
4
  • \$\begingroup\$ Is there any negative side effects of using a FileOutputStream? I think there is not. I also now buffered the output of the FileOutputStream for better performance. \$\endgroup\$ Commented Jun 12, 2016 at 15:04
  • \$\begingroup\$ @Gala: Well since the FileWriter API is designed for String handling, it provides more convienient methods and probably also has less pitfalls. \$\endgroup\$
    – user140547
    Commented Jun 12, 2016 at 16:14
  • \$\begingroup\$ I'll stick with the FileOutputStream. \$\endgroup\$ Commented Jun 12, 2016 at 16:33
  • \$\begingroup\$ The advantage of writers are that you specify the charset at the constructor, instead of at every call \$\endgroup\$
    – Ferrybig
    Commented Jun 12, 2016 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.