package org.basex.server; import static org.basex.util.Token.*; import java.io.FileOutputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.basex.core.Context; import org.basex.core.Prop; import org.basex.io.IOFile; import org.basex.util.TokenBuilder; import org.basex.util.Util; /** * This class writes logging information to disk. * * @author BaseX Team 2005-12, BSD License * @author Andreas Weiler */ public final class Log { /** Date format. */ private static final DateFormat DATE = new SimpleDateFormat("yyyy-MM-dd"); /** Time format. */ private static final DateFormat TIME = new SimpleDateFormat("HH:mm:ss.SSS"); /** Quiet flag. */ private final boolean quiet; /** Logging directory. */ private final IOFile dir; /** Start date of log. */ private String start; /** Output stream. */ private FileOutputStream fos; /** * Constructor. * @param ctx database context * @param q quiet flag (no logging) */ public Log(final Context ctx, final boolean q) { dir = ctx.mprop.dbpath(".logs"); quiet = q; if(!q) create(new Date()); } /** * Writes an entry to the log file. * @param str strings to be written */ public synchronized void write(final Object... str) { if(quiet) return; // check if current log file is still up-to-date final Date now = new Date(); if(!start.equals(DATE.format(now))) { close(); create(now); } // construct log text final TokenBuilder tb = new TokenBuilder(TIME.format(now)); for(final Object s : str) { tb.add('\t'); tb.add(chop(token(s.toString().replaceAll("[\\r\\n ]+", " ")), 1000)); } tb.add(Prop.NL); // write text and flush log file try { fos.write(tb.finish()); fos.flush(); } catch(final Exception ex) { Util.debug(ex); } } /** * Creates a log file. * @param d date, used for file name */ private synchronized void create(final Date d) { dir.md(); start = DATE.format(d); try { fos = new FileOutputStream(new IOFile(dir, start + ".log").file(), true); } catch(final IOException ex) { Util.stack(ex); } } /** * Closes the log file. */ public synchronized void close() { if(quiet) return; try { fos.close(); } catch(final IOException ex) { Util.stack(ex); } } }