SessionLogger.java [src/csip] Revision:   Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API and application suite.
 *
 * 2012-2022, Olaf David and others, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package csip;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * Custom SessionLogger with system delegate.
 *
 * @author od
 */
public final class SessionLogger {

  private static final int offValue = Level.OFF.intValue();
  private volatile Level levelObject;
  private volatile int levelValue;  // current effective level value

  private static Formatter f = new SimpleFormatter();
  private Logger delegate;
  private PrintWriter w;
  private String name = "?";

  final Object lock = new Object();


  SessionLogger(File dir, String service, String suid, String level) {
    delegate = Config.LOG;
    setLevel(Level.parse(level));
    if (service != null && suid != null)
      name = service + " " + suid;
    try {
      if (dir != null)
        w = new PrintWriter(new File(dir, ModelDataService.LOG_FILE));
    } catch (FileNotFoundException ex) {
      delegate.log(Level.SEVERE, null, ex);
    }
  }


  void setName(String service_suid) {
    name = service_suid;
  }


  /**
   * Null Logger. Nothing gets logged this way.
   */
  public SessionLogger() {
    this(null, null, null, "OFF");
  }


  public void severe(String msg) {
    log(Level.SEVERE, msg);
  }


  public void warning(String msg) {
    log(Level.WARNING, msg);
  }


  public void info(String msg) {
    log(Level.INFO, msg);
  }


  public void config(String msg) {
    log(Level.CONFIG, msg);
  }


  public void fine(String msg) {
    log(Level.FINE, msg);
  }


  public void finer(String msg) {
    log(Level.FINER, msg);
  }


  public void finest(String msg) {
    log(Level.FINEST, msg);
  }


  public void log(Level level, String msg, Throwable t) {
    if (!isLoggable(level))
      return;
    LogRecord lr = new LogRecord(level, msg);
    lr.setThrown(t);
    doLog(lr);
  }


  public void log(Level level, String msg) {
    if (!isLoggable(level))
      return;
    doLog(new LogRecord(level, msg));
  }


  public void log(Level level, String msg, Object... params) {
    if (!isLoggable(level))
      return;
    LogRecord lr = new LogRecord(level, msg);
    lr.setParameters(params);
    doLog(lr);
  }


  private void doLog(LogRecord lr) {
    lr.setLoggerName(name);
    synchronized (lock) {
      if (w != null) {
        w.print(f.format(lr));
        w.flush();
      }
    }
    if (delegate != null)
      delegate.log(lr);
  }


  void close() {
    synchronized (lock) {
      if (w != null) {
        info("closing session:." + name);
        w.flush();
        w.close();
        w = null;
      }
    }
  }


  public boolean isLoggable(Level level) {
    if (levelValue == offValue || level.intValue() < levelValue)
      return false;
    return true;
  }


  public void setLevel(Level newLevel) throws SecurityException {
    levelObject = newLevel;
    levelValue = levelObject.intValue();
    if (delegate != null)
      delegate.setLevel(newLevel);
  }


  /**
   * Get the Log level.
   *
   * @return the current log level
   */
  public Level getLevel() {
    return levelObject;
  }


  public static void main(String[] args) {
    Config.startup();
    SessionLogger l = new SessionLogger(new File("/tmp"), "m/me", "1234-65", "WARNING");
    l.severe("bad");
    l.warning("This is a warning test.");
    l.info("This is a info test.");
    l.config("This is a config test.");
    l.fine("This is a fine test.");
    l.finer("This is a finer test.");
    l.finest("This is a finest test.");
    l.close();

//    Logger ll = Logger.getLogger("abc");
//    System.out.println(ll.getLevel());
  }
}