/* * Copyright 2014,2016 Cel Skeggs * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. */ package ccre.log; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.Date; import ccre.scheduler.Scheduler; import ccre.storage.Storage; import ccre.time.Time; /** * A logging tool that stores logging message in a file on the current computer * or robot. * * @author skeggsc */ public class FileLogger implements LoggingTarget { /** * Register a new FileLogger writing to a unique file with the logging * manager. */ public static void register() { try { int i = 0; while (true) { InputStream oi = Storage.openInput("log-" + i); if (oi == null) { break; } oi.close(); i++; } Logger.addTarget(new FileLogger("log-" + i)); } catch (IOException ex) { Logger.warning("Could not set up File logging!", ex); } } /** * The PrintStream to log outputs to. */ private final PrintStream pstream; /** * Create a new FileLogger writing to the specified output file. * * @param fname The filename to write to * @throws IOException If an IO Exception occurs. */ public FileLogger(String fname) throws IOException { this(Storage.openOutput(fname)); } /** * Create a new FileLogger writing to the specified output stream. * * @param out The output stream to write to. */ public FileLogger(OutputStream out) { this(out instanceof PrintStream ? (PrintStream) out : new PrintStream(out)); } /** * Create a new FileLogger writing to the specified PrintStream. * * @param pstream The stream to write to. */ public FileLogger(final PrintStream pstream) { this.pstream = pstream; long now = Time.currentTimeMillis(); pstream.println("Logging began at " + new Date(System.currentTimeMillis()) + " [" + now + "]"); Scheduler.schedulePeriodicNanos("file-logger-flush", 10 * Time.NANOSECONDS_PER_SECOND, () -> { synchronized (FileLogger.this) { pstream.println("Logging continues at " + new Date()); pstream.flush(); } }); } @Override public synchronized void log(LogLevel level, String message, Throwable throwable) { pstream.println("[" + (Time.currentTimeMillis()) + " " + level + "] " + message); if (throwable != null) { throwable.printStackTrace(pstream); } pstream.flush(); } @Override public synchronized void log(LogLevel level, String message, String extended) { pstream.println("[" + (Time.currentTimeMillis()) + " " + level + "] " + message); if (extended != null) { int i = extended.length(); while (i != 0 && extended.charAt(i - 1) <= 32) { i -= 1; } if (i != 0) { pstream.println(extended); } } pstream.flush(); } }