[tor-commits] [onionoo/master] logging java source changes.

karsten at torproject.org karsten at torproject.org
Thu Sep 4 09:33:07 UTC 2014


commit 6139c32c2ab8fc1cc00cae2d9ae1efb19dacae17
Author: iwakeh <iwakeh at users.ourproject.org>
Date:   Mon Sep 1 17:30:00 2014 +0000

    logging java source changes.
---
 .../java/org/torproject/onionoo/cron/Main.java     |   51 ++++++-----
 .../torproject/onionoo/docs/BandwidthStatus.java   |    9 +-
 .../org/torproject/onionoo/docs/ClientsStatus.java |    7 +-
 .../torproject/onionoo/docs/DateTimeHelper.java    |   15 +++-
 .../org/torproject/onionoo/docs/DocumentStore.java |   92 ++++++++++----------
 .../org/torproject/onionoo/docs/NodeStatus.java    |   19 ++--
 .../org/torproject/onionoo/docs/UptimeHistory.java |    2 +-
 .../org/torproject/onionoo/docs/UptimeStatus.java  |    8 +-
 .../org/torproject/onionoo/docs/WeightsStatus.java |    9 +-
 .../onionoo/server/PerformanceMetrics.java         |   42 ++++++---
 .../onionoo/updater/ClientsStatusUpdater.java      |    6 +-
 .../onionoo/updater/DescriptorDownloader.java      |   22 +++--
 .../onionoo/updater/DescriptorQueue.java           |   27 +++---
 .../onionoo/updater/DescriptorSource.java          |   52 +++++++----
 .../torproject/onionoo/updater/LookupService.java  |   48 +++++-----
 .../onionoo/updater/NodeDetailsStatusUpdater.java  |   35 ++++----
 .../onionoo/updater/ReverseDomainNameResolver.java |   20 +++--
 .../onionoo/updater/StatusUpdateRunner.java        |   19 ++--
 .../onionoo/updater/UptimeStatusUpdater.java       |    8 +-
 .../torproject/onionoo/util/FormattingUtils.java   |   31 +++++++
 .../java/org/torproject/onionoo/util/LockFile.java |   10 ++-
 .../java/org/torproject/onionoo/util/Logger.java   |   82 -----------------
 .../onionoo/writer/BandwidthDocumentWriter.java    |    8 +-
 .../onionoo/writer/ClientsDocumentWriter.java      |   13 ++-
 .../onionoo/writer/DetailsDocumentWriter.java      |    8 +-
 .../onionoo/writer/DocumentWriterRunner.java       |    9 +-
 .../onionoo/writer/SummaryDocumentWriter.java      |   17 ++--
 .../onionoo/writer/UptimeDocumentWriter.java       |   13 ++-
 .../onionoo/writer/WeightsDocumentWriter.java      |   10 ++-
 29 files changed, 390 insertions(+), 302 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/cron/Main.java b/src/main/java/org/torproject/onionoo/cron/Main.java
index bd4b95a..d9cb1b1 100644
--- a/src/main/java/org/torproject/onionoo/cron/Main.java
+++ b/src/main/java/org/torproject/onionoo/cron/Main.java
@@ -2,76 +2,79 @@
  * See LICENSE for licensing information */
 package org.torproject.onionoo.cron;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.StatusUpdateRunner;
 import org.torproject.onionoo.util.LockFile;
-import org.torproject.onionoo.util.Logger;
 import org.torproject.onionoo.writer.DocumentWriterRunner;
 
 /* Update search data and status data files. */
 public class Main {
 
+  private static Logger log = LoggerFactory.getLogger(Main.class);
+
   private Main() {
   }
 
   public static void main(String[] args) {
-
+    log.debug("Started ...");
     LockFile lf = new LockFile();
-    Logger.setTime();
-    Logger.printStatus("Initializing.");
+    log.info("Initializing.");
     if (lf.acquireLock()) {
-      Logger.printStatusTime("Acquired lock");
+      log.info("Acquired lock");
     } else {
-      Logger.printErrorTime("Could not acquire lock.  Is Onionoo "
+      log.error("Could not acquire lock.  Is Onionoo "
           + "already running?  Terminating");
       return;
     }
+    log.debug(" ... running .... ");
 
     DescriptorSource dso = DescriptorSourceFactory.getDescriptorSource();
-    Logger.printStatusTime("Initialized descriptor source");
+    log.info("Initialized descriptor source");
     DocumentStore ds = DocumentStoreFactory.getDocumentStore();
-    Logger.printStatusTime("Initialized document store");
+    log.info("Initialized document store");
     StatusUpdateRunner sur = new StatusUpdateRunner();
-    Logger.printStatusTime("Initialized status update runner");
+    log.info("Initialized status update runner");
     DocumentWriterRunner dwr = new DocumentWriterRunner();
-    Logger.printStatusTime("Initialized document writer runner");
+    log.info("Initialized document writer runner");
 
-    Logger.printStatus("Downloading descriptors.");
+    log.info("Downloading descriptors.");
     dso.downloadDescriptors();
 
-    Logger.printStatus("Reading descriptors.");
+    log.info("Reading descriptors.");
     dso.readDescriptors();
 
-    Logger.printStatus("Updating internal status files.");
+    log.info("Updating internal status files.");
     sur.updateStatuses();
 
-    Logger.printStatus("Updating document files.");
+    log.info("Updating document files.");
     dwr.writeDocuments();
 
-    Logger.printStatus("Shutting down.");
+    log.info("Shutting down.");
     dso.writeHistoryFiles();
-    Logger.printStatusTime("Wrote parse histories");
+    log.info("Wrote parse histories");
     ds.flushDocumentCache();
-    Logger.printStatusTime("Flushed document cache");
+    log.info("Flushed document cache");
 
-    Logger.printStatus("Gathering statistics.");
+    log.info("Gathering statistics.");
     sur.logStatistics();
     dwr.logStatistics();
-    Logger.printStatistics("Descriptor source", dso.getStatsString());
-    Logger.printStatistics("Document store", ds.getStatsString());
+    log.info("Descriptor source", dso.getStatsString());
+    log.info("Document store", ds.getStatsString());
 
-    Logger.printStatus("Releasing lock.");
+    log.info("Releasing lock.");
     if (lf.releaseLock()) {
-      Logger.printStatusTime("Released lock");
+      log.info("Released lock");
     } else {
-      Logger.printErrorTime("Could not release lock.  The next "
+      log.error("Could not release lock.  The next "
           + "execution may not start as expected");
     }
 
-    Logger.printStatus("Terminating.");
+    log.info("Terminating.");
   }
 }
 
diff --git a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
index 3a0d6ba..4c6ea79 100644
--- a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
@@ -7,11 +7,16 @@ import java.util.Scanner;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.descriptor.BandwidthHistory;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class BandwidthStatus extends Document {
 
+  private static Logger log = LoggerFactory.getLogger(
+      BandwidthStatus.class);
+
   private transient boolean isDirty = false;
   public boolean isDirty() {
     return this.isDirty;
@@ -44,7 +49,7 @@ public class BandwidthStatus extends Document {
       String line = s.nextLine();
       String[] parts = line.split(" ");
       if (parts.length != 6) {
-        System.err.println("Illegal line '" + line + "' in bandwidth "
+        log.error("Illegal line '" + line + "' in bandwidth "
             + "history.  Skipping this line.");
         continue;
       }
@@ -53,7 +58,7 @@ public class BandwidthStatus extends Document {
       long startMillis = DateTimeHelper.parse(parts[1] + " " + parts[2]);
       long endMillis = DateTimeHelper.parse(parts[3] + " " + parts[4]);
       if (startMillis < 0L || endMillis < 0L) {
-        System.err.println("Could not parse timestamp while reading "
+        log.error("Could not parse timestamp while reading "
             + "bandwidth history.  Skipping.");
         break;
       }
diff --git a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
index 7257faa..a15ff56 100644
--- a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
@@ -6,10 +6,15 @@ import java.util.Scanner;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class ClientsStatus extends Document {
 
+  private static Logger log = LoggerFactory.getLogger(
+      ClientsStatus.class);
+
   private transient boolean isDirty = false;
   public boolean isDirty() {
     return this.isDirty;
@@ -35,7 +40,7 @@ public class ClientsStatus extends Document {
       if (parsedLine != null) {
         this.history.add(parsedLine);
       } else {
-        System.err.println("Could not parse clients history line '"
+        log.error("Could not parse clients history line '"
             + line + "'.  Skipping.");
       }
     }
diff --git a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
index 78aa78f..27b54a0 100644
--- a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
+++ b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
@@ -9,8 +9,16 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.TimeZone;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class DateTimeHelper {
 
+  public final static long NO_TIME_AVAILABLE = -1L;
+
+  private final static Logger log = LoggerFactory.getLogger(
+      DateTimeHelper.class);
+
   private DateTimeHelper() {
   }
 
@@ -79,10 +87,15 @@ public class DateTimeHelper {
   }
 
   public static long parse(String string, String format) {
+    if (null == string) {
+      log.warn("Date String was null.");
+      return NO_TIME_AVAILABLE;
+    }
     try {
       return getDateFormat(format).parse(string).getTime();
     } catch (ParseException e) {
-      return -1L;
+      log.warn(e.getMessage(), e);
+      return NO_TIME_AVAILABLE;
     }
   }
 
diff --git a/src/main/java/org/torproject/onionoo/docs/DocumentStore.java b/src/main/java/org/torproject/onionoo/docs/DocumentStore.java
index 73da1ae..e3261e4 100644
--- a/src/main/java/org/torproject/onionoo/docs/DocumentStore.java
+++ b/src/main/java/org/torproject/onionoo/docs/DocumentStore.java
@@ -21,7 +21,9 @@ import java.util.Stack;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import org.torproject.onionoo.util.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.torproject.onionoo.util.FormattingUtils;
 import org.torproject.onionoo.util.Time;
 import org.torproject.onionoo.util.TimeFactory;
 
@@ -36,6 +38,9 @@ import com.google.gson.JsonParseException;
 // TODO Also look into simple key-value stores instead of real databases.
 public class DocumentStore {
 
+  private static Logger log = LoggerFactory.getLogger(
+      DocumentStore.class);
+
   private final File statusDir = new File("status");
 
   private File outDir = new File("out");
@@ -102,9 +107,8 @@ public class DocumentStore {
           this.listedFiles += parsedNodeStatuses.size();
           this.listOperations++;
         } catch (IOException e) {
-          System.err.println("Could not read file '"
-              + summaryFile.getAbsolutePath() + "'.");
-          e.printStackTrace();
+          log.error("Could not read file '"
+              + summaryFile.getAbsolutePath() + "'.", e);
         }
       }
     }
@@ -145,13 +149,11 @@ public class DocumentStore {
           this.listedFiles += parsedSummaryDocuments.size();
           this.listOperations++;
         } catch (IOException e) {
-          System.err.println("Could not read file '"
-              + summaryFile.getAbsolutePath() + "'.");
-          e.printStackTrace();
+          log.error("Could not read file '"
+              + summaryFile.getAbsolutePath() + "'.", e);
         } catch (JsonParseException e) {
-          System.err.println("Could not parse summary document '" + line
-              + "' in file '" + summaryFile.getAbsolutePath() + "'.");
-          e.printStackTrace();
+          log.error("Could not parse summary document '" + line
+              + "' in file '" + summaryFile.getAbsolutePath() + "'.", e);
         }
       }
     }
@@ -289,7 +291,7 @@ public class DocumentStore {
         document instanceof UptimeStatus) {
       documentString = document.toDocumentString();
     } else {
-      System.err.println("Serializing is not supported for type "
+      log.error("Serializing is not supported for type "
           + document.getClass().getName() + ".");
       return false;
     }
@@ -306,9 +308,8 @@ public class DocumentStore {
       this.storedFiles++;
       this.storedBytes += documentString.length();
     } catch (IOException e) {
-      System.err.println("Could not write file '"
-          + documentFile.getAbsolutePath() + "'.");
-      e.printStackTrace();
+      log.error("Could not write file '"
+          + documentFile.getAbsolutePath() + "'.", e);
       return false;
     }
     return true;
@@ -391,7 +392,7 @@ public class DocumentStore {
     if (documentFile == null || !documentFile.exists()) {
       return null;
     } else if (documentFile.isDirectory()) {
-      System.err.println("Could not read file '"
+      log.error("Could not read file '"
           + documentFile.getAbsolutePath() + "', because it is a "
           + "directory.");
       return null;
@@ -415,9 +416,8 @@ public class DocumentStore {
       this.retrievedFiles++;
       this.retrievedBytes += documentString.length();
     } catch (IOException e) {
-      System.err.println("Could not read file '"
-          + documentFile.getAbsolutePath() + "'.");
-      e.printStackTrace();
+      log.error("Could not read file '"
+          + documentFile.getAbsolutePath() + "'.", e);
       return null;
     }
     T result = null;
@@ -440,7 +440,7 @@ public class DocumentStore {
       return this.retrieveParsedDocumentFile(documentType, "{"
           + documentString + "}");
     } else {
-      System.err.println("Parsing is not supported for type "
+      log.error("Parsing is not supported for type "
           + documentType.getName() + ".");
     }
     return result;
@@ -454,13 +454,13 @@ public class DocumentStore {
       result.fromDocumentString(documentString);
     } catch (InstantiationException e) {
       /* Handle below. */
-      e.printStackTrace();
+      log.error(e.getMessage(), e);
     } catch (IllegalAccessException e) {
       /* Handle below. */
-      e.printStackTrace();
+      log.error(e.getMessage(), e);
     }
     if (result == null) {
-      System.err.println("Could not initialize parsed status file of "
+      log.error("Could not initialize parsed status file of "
           + "type " + documentType.getName() + ".");
     }
     return result;
@@ -474,10 +474,10 @@ public class DocumentStore {
       result = gson.fromJson(documentString, documentType);
     } catch (JsonParseException e) {
       /* Handle below. */
-      e.printStackTrace();
+      log.error(e.getMessage(), e);
     }
     if (result == null) {
-      System.err.println("Could not initialize parsed document of type "
+      log.error("Could not initialize parsed document of type "
           + documentType.getName() + ".");
     }
     return result;
@@ -491,13 +491,13 @@ public class DocumentStore {
       result.setDocumentString(documentString);
     } catch (InstantiationException e) {
       /* Handle below. */
-      e.printStackTrace();
+      log.error(e.getMessage(), e);
     } catch (IllegalAccessException e) {
       /* Handle below. */
-      e.printStackTrace();
+      log.error(e.getMessage(), e);
     }
     if (result == null) {
-      System.err.println("Could not initialize unparsed document of type "
+      log.error("Could not initialize unparsed document of type "
           + documentType.getName() + ".");
     }
     return result;
@@ -536,7 +536,7 @@ public class DocumentStore {
       Class<T> documentType, String fingerprint) {
     File documentFile = this.getDocumentFile(documentType, fingerprint);
     if (documentFile == null || !documentFile.delete()) {
-      System.err.println("Could not delete file '"
+      log.error("Could not delete file '"
           + documentFile.getAbsolutePath() + "'.");
       return false;
     }
@@ -655,7 +655,7 @@ public class DocumentStore {
       if (line != null) {
         sb.append(line + "\n");
       } else {
-        System.err.println("Could not serialize relay node status '"
+        log.error("Could not serialize relay node status '"
             + relay.getFingerprint() + "'");
       }
     }
@@ -664,7 +664,7 @@ public class DocumentStore {
       if (line != null) {
         sb.append(line + "\n");
       } else {
-        System.err.println("Could not serialize bridge node status '"
+        log.error("Could not serialize bridge node status '"
             + bridge.getFingerprint() + "'");
       }
     }
@@ -677,9 +677,8 @@ public class DocumentStore {
       this.storedFiles++;
       this.storedBytes += documentString.length();
     } catch (IOException e) {
-      System.err.println("Could not write file '"
-          + summaryFile.getAbsolutePath() + "'.");
-      e.printStackTrace();
+      log.error("Could not write file '"
+          + summaryFile.getAbsolutePath() + "'.", e);
     }
   }
 
@@ -692,7 +691,7 @@ public class DocumentStore {
       if (line != null) {
         sb.append(line + "\n");
       } else {
-        System.err.println("Could not serialize relay summary document '"
+        log.error("Could not serialize relay summary document '"
             + summaryDocument.getFingerprint() + "'");
       }
     }
@@ -706,9 +705,8 @@ public class DocumentStore {
       this.storedFiles++;
       this.storedBytes += documentString.length();
     } catch (IOException e) {
-      System.err.println("Could not write file '"
-          + summaryFile.getAbsolutePath() + "'.");
-      e.printStackTrace();
+      log.error("Could not write file '"
+          + summaryFile.getAbsolutePath() + "'.", e);
     }
   }
 
@@ -726,26 +724,26 @@ public class DocumentStore {
       this.storedFiles++;
       this.storedBytes += documentString.length();
     } catch (IOException e) {
-      System.err.println("Could not write file '"
-          + updateFile.getAbsolutePath() + "'.");
-      e.printStackTrace();
+      log.error("Could not write file '"
+          + updateFile.getAbsolutePath() + "'.", e);
     }
   }
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(listOperations)
+    sb.append("    " + FormattingUtils.formatDecimalNumber(listOperations)
         + " list operations performed\n");
-    sb.append("    " + Logger.formatDecimalNumber(listedFiles)
+    sb.append("    " + FormattingUtils.formatDecimalNumber(listedFiles)
         + " files listed\n");
-    sb.append("    " + Logger.formatDecimalNumber(storedFiles)
+    sb.append("    " + FormattingUtils.formatDecimalNumber(storedFiles)
         + " files stored\n");
-    sb.append("    " + Logger.formatBytes(storedBytes) + " stored\n");
-    sb.append("    " + Logger.formatDecimalNumber(retrievedFiles)
+    sb.append("    " + FormattingUtils.formatBytes(storedBytes)
+        + " stored\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(retrievedFiles)
         + " files retrieved\n");
-    sb.append("    " + Logger.formatBytes(retrievedBytes)
+    sb.append("    " + FormattingUtils.formatBytes(retrievedBytes)
         + " retrieved\n");
-    sb.append("    " + Logger.formatDecimalNumber(removedFiles)
+    sb.append("    " + FormattingUtils.formatDecimalNumber(removedFiles)
         + " files removed\n");
     return sb.toString();
   }
diff --git a/src/main/java/org/torproject/onionoo/docs/NodeStatus.java b/src/main/java/org/torproject/onionoo/docs/NodeStatus.java
index fa31968..0df8847 100644
--- a/src/main/java/org/torproject/onionoo/docs/NodeStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/NodeStatus.java
@@ -15,11 +15,16 @@ import java.util.TreeSet;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /* Store search data of a single relay that was running in the past seven
  * days. */
 public class NodeStatus extends Document {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      NodeStatus.class);
+
   private boolean isRelay;
   public boolean isRelay() {
     return this.isRelay;
@@ -377,7 +382,7 @@ public class NodeStatus extends Document {
       String[] parts = documentString.trim().split(separator);
       isRelay = parts[0].equals("r");
       if (parts.length < 9) {
-        System.err.println("Too few space-separated values in line '"
+        log.error("Too few space-separated values in line '"
             + documentString.trim() + "'.  Skipping.");
         return null;
       }
@@ -389,7 +394,7 @@ public class NodeStatus extends Document {
       if (addresses.contains(";")) {
         String[] addressParts = addresses.split(";", -1);
         if (addressParts.length != 3) {
-          System.err.println("Invalid addresses entry in line '"
+          log.error("Invalid addresses entry in line '"
               + documentString.trim() + "'.  Skipping.");
           return null;
         }
@@ -407,7 +412,7 @@ public class NodeStatus extends Document {
       }
       lastSeenMillis = DateTimeHelper.parse(parts[4] + " " + parts[5]);
       if (lastSeenMillis < 0L) {
-        System.err.println("Parse exception while parsing node status "
+        log.error("Parse exception while parsing node status "
             + "line '" + documentString + "'.  Skipping.");
         return null;
       }
@@ -440,7 +445,7 @@ public class NodeStatus extends Document {
         firstSeenMillis = DateTimeHelper.parse(parts[15] + " "
             + parts[16]);
         if (firstSeenMillis < 0L) {
-          System.err.println("Parse exception while parsing node status "
+          log.error("Parse exception while parsing node status "
               + "line '" + documentString + "'.  Skipping.");
           return null;
         }
@@ -450,7 +455,7 @@ public class NodeStatus extends Document {
         lastChangedAddresses = DateTimeHelper.parse(parts[17] + " "
             + parts[18]);
         if (lastChangedAddresses < 0L) {
-          System.err.println("Parse exception while parsing node status "
+          log.error("Parse exception while parsing node status "
               + "line '" + documentString + "'.  Skipping.");
           return null;
         }
@@ -470,14 +475,14 @@ public class NodeStatus extends Document {
             parts[22].split(";")));
       }
     } catch (NumberFormatException e) {
-      System.err.println("Number format exception while parsing node "
+      log.error("Number format exception while parsing node "
           + "status line '" + documentString + "': " + e.getMessage()
           + ".  Skipping.");
       return null;
     } catch (Exception e) {
       /* This catch block is only here to handle yet unknown errors.  It
        * should go away once we're sure what kind of errors can occur. */
-      System.err.println("Unknown exception while parsing node status "
+      log.error("Unknown exception while parsing node status "
           + "line '" + documentString + "': " + e.getMessage() + ".  "
           + "Skipping.");
       return null;
diff --git a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
index d2655d5..0d27242 100644
--- a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
+++ b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
@@ -39,7 +39,7 @@ public class UptimeHistory
     }
     long startMillis = DateTimeHelper.parse(parts[1],
           DateTimeHelper.DATEHOUR_NOSPACE_FORMAT);
-    if (startMillis < 0L) {
+    if (DateTimeHelper.NO_TIME_AVAILABLE == startMillis) {
       return null;
     }
     int uptimeHours = -1;
diff --git a/src/main/java/org/torproject/onionoo/docs/UptimeStatus.java b/src/main/java/org/torproject/onionoo/docs/UptimeStatus.java
index 3bc268a..eaa28ff 100644
--- a/src/main/java/org/torproject/onionoo/docs/UptimeStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/UptimeStatus.java
@@ -6,8 +6,14 @@ import java.util.Scanner;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class UptimeStatus extends Document {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      UptimeStatus.class);
+
   private transient boolean isDirty = false;
   public boolean isDirty() {
     return this.isDirty;
@@ -46,7 +52,7 @@ public class UptimeStatus extends Document {
           this.bridgeHistory.add(parsedLine);
         }
       } else {
-        System.err.println("Could not parse uptime history line '"
+        log.error("Could not parse uptime history line '"
             + line + "'.  Skipping.");
       }
     }
diff --git a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
index e49dfb1..e20112e 100644
--- a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
@@ -7,10 +7,15 @@ import java.util.Scanner;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class WeightsStatus extends Document {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      WeightsStatus.class);
+
   private transient boolean isDirty = false;
   public boolean isDirty() {
     return this.isDirty;
@@ -51,7 +56,7 @@ public class WeightsStatus extends Document {
         continue;
       }
       if (parts.length != 9 && parts.length != 11) {
-        System.err.println("Illegal line '" + line + "' in weights "
+        log.error("Illegal line '" + line + "' in weights "
               + "status file.  Skipping this line.");
         continue;
       }
@@ -65,7 +70,7 @@ public class WeightsStatus extends Document {
       long freshUntilMillis = DateTimeHelper.parse(parts[2] + " "
           + parts[3]);
       if (validAfterMillis < 0L || freshUntilMillis < 0L) {
-        System.err.println("Could not parse timestamp while reading "
+        log.error("Could not parse timestamp while reading "
             + "weights status file.  Skipping.");
         break;
       }
diff --git a/src/main/java/org/torproject/onionoo/server/PerformanceMetrics.java b/src/main/java/org/torproject/onionoo/server/PerformanceMetrics.java
index 9d9f3be..e764601 100644
--- a/src/main/java/org/torproject/onionoo/server/PerformanceMetrics.java
+++ b/src/main/java/org/torproject/onionoo/server/PerformanceMetrics.java
@@ -14,6 +14,9 @@ import java.util.TimeZone;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.util.Time;
 import org.torproject.onionoo.util.TimeFactory;
 
@@ -117,6 +120,9 @@ class IntegerDistribution {
 
 public class PerformanceMetrics {
 
+  private static final Logger log = LoggerFactory.getLogger(
+      PerformanceMetrics.class);
+
   private static final Object lock = new Object();
 
   private static Time time;
@@ -155,25 +161,25 @@ public class PerformanceMetrics {
         SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
             "yyyy-MM-dd HH:mm:ss");
         dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
-        System.err.println("Request statistics ("
+        log.info("Request statistics ("
             + dateTimeFormat.format(lastLoggedMillis
             + LOG_INTERVAL_MILLIS) + ", " + (LOG_INTERVAL_SECONDS)
             + " s):");
-        System.err.println("  Total processed requests: "
+        log.info("  Total processed requests: "
             + totalProcessedRequests);
-        System.err.println("  Most frequently requested resource: "
+        log.info("  Most frequently requested resource: "
             + requestsByResourceType);
-        System.err.println("  Most frequently requested parameter "
+        log.info("  Most frequently requested parameter "
             + "combinations: " + requestsByParameters);
-        System.err.println("  Matching relays per request: "
+        log.info("  Matching relays per request: "
             + matchingRelayDocuments);
-        System.err.println("  Matching bridges per request: "
+        log.info("  Matching bridges per request: "
             + matchingBridgeDocuments);
-        System.err.println("  Written characters per response: "
+        log.info("  Written characters per response: "
             + writtenChars);
-        System.err.println("  Milliseconds to handle request: "
+        log.info("  Milliseconds to handle request: "
             + handleRequestMillis);
-        System.err.println("  Milliseconds to build response: "
+        log.info("  Milliseconds to build response: "
             + buildResponseMillis);
         totalProcessedRequests.clear();
         requestsByResourceType.clear();
@@ -189,15 +195,25 @@ public class PerformanceMetrics {
             LOG_INTERVAL_MILLIS);
       }
       totalProcessedRequests.increment();
-      handleRequestMillis.addLong(parsedRequestMillis
-          - receivedRequestMillis);
+      long handlingTime = parsedRequestMillis - receivedRequestMillis;
+      if (handlingTime > DateTimeHelper.ONE_SECOND) {
+        log.warn("longer request handling: " + handlingTime + " ms for "
+            + resourceType + " params: " + parameterKeys + " and "
+            + charsWritten + " chars.");
+      }
+      handleRequestMillis.addLong(handlingTime);
       requestsByResourceType.addString(resourceType);
       requestsByParameters.addString(parameterKeys.toString());
       matchingRelayDocuments.addLong(relayDocumentsWritten);
       matchingBridgeDocuments.addLong(bridgeDocumentsWritten);
       writtenChars.addLong(charsWritten);
-      buildResponseMillis.addLong(writtenResponseMillis
-          - parsedRequestMillis);
+      long responseTime = writtenResponseMillis - parsedRequestMillis;
+      if (responseTime > DateTimeHelper.ONE_SECOND) {
+        log.warn("longer response building: " + responseTime + " ms for "
+            + resourceType + " params: " + parameterKeys + " and "
+            + charsWritten + " chars.");
+      }
+      buildResponseMillis.addLong(responseTime);
     }
   }
 
diff --git a/src/main/java/org/torproject/onionoo/updater/ClientsStatusUpdater.java b/src/main/java/org/torproject/onionoo/updater/ClientsStatusUpdater.java
index 4c21032..f3f2e0f 100644
--- a/src/main/java/org/torproject/onionoo/updater/ClientsStatusUpdater.java
+++ b/src/main/java/org/torproject/onionoo/updater/ClientsStatusUpdater.java
@@ -15,7 +15,7 @@ import org.torproject.onionoo.docs.ClientsStatus;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 
 /*
  * Example extra-info descriptor used as input:
@@ -164,10 +164,10 @@ public class ClientsStatusUpdater implements DescriptorListener,
     }
     StringBuilder sb = new StringBuilder();
     sb.append("    "
-        + Logger.formatDecimalNumber(newIntervals / 2)
+        + FormattingUtils.formatDecimalNumber(newIntervals / 2)
         + " client statistics processed from extra-info descriptors\n");
     sb.append("    "
-        + Logger.formatDecimalNumber(this.newResponses.size())
+        + FormattingUtils.formatDecimalNumber(this.newResponses.size())
         + " client status files updated\n");
     return sb.toString();
   }
diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java b/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java
index 60d8d45..9e2f80d 100644
--- a/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java
+++ b/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java
@@ -14,8 +14,14 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.zip.GZIPInputStream;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 class DescriptorDownloader {
 
+  private static Logger log = LoggerFactory.getLogger(
+      DescriptorDownloader.class);
+
   private final String protocolHostNameResourcePrefix =
       "https://collector.torproject.org/recent/";
 
@@ -50,7 +56,7 @@ class DescriptorDownloader {
       this.directory = "bridge-pool-assignments/";
       break;
     default:
-      System.err.println("Unknown descriptor type.");
+      log.error("Unknown descriptor type.");
       return;
     }
   }
@@ -78,7 +84,7 @@ class DescriptorDownloader {
       huc.setRequestMethod("GET");
       huc.connect();
       if (huc.getResponseCode() != 200) {
-        System.err.println("Could not fetch " + directoryUrl
+        log.error("Could not fetch " + directoryUrl
             + ": " + huc.getResponseCode() + " "
             + huc.getResponseMessage() + ".  Skipping.");
         return 0;
@@ -104,8 +110,8 @@ class DescriptorDownloader {
       }
       br.close();
     } catch (IOException e) {
-      System.err.println("Could not fetch or parse " + directoryUrl
-          + ".  Skipping.");
+      log.error("Could not fetch or parse " + directoryUrl
+        + ".  Skipping. Reason: " + e.getMessage());
     }
     return this.remoteFiles.size();
   }
@@ -129,7 +135,7 @@ class DescriptorDownloader {
         huc.addRequestProperty("Accept-Encoding", "gzip");
         huc.connect();
         if (huc.getResponseCode() != 200) {
-          System.err.println("Could not fetch " + fileUrl
+          log.error("Could not fetch \n\t" + fileUrl
               + ": " + huc.getResponseCode() + " "
               + huc.getResponseMessage() + ".  Skipping.");
           continue;
@@ -158,8 +164,8 @@ class DescriptorDownloader {
         }
         fetchedFiles++;
       } catch (IOException e) {
-        System.err.println("Could not fetch or store " + fileUrl
-            + ".  Skipping.");
+        log.error("Could not fetch or store \n\t" + fileUrl
+            + ".  Skipping.\n\tReason: " + e.getMessage());
       }
     }
     return fetchedFiles;
@@ -175,4 +181,4 @@ class DescriptorDownloader {
     }
     return deletedFiles;
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java b/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java
index 96362c5..8ba4260 100644
--- a/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java
+++ b/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java
@@ -12,6 +12,8 @@ import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.descriptor.Descriptor;
 import org.torproject.descriptor.DescriptorFile;
 import org.torproject.descriptor.DescriptorReader;
@@ -19,6 +21,9 @@ import org.torproject.descriptor.DescriptorSourceFactory;
 
 class DescriptorQueue {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      DescriptorQueue.class);
+
   private File inDir;
 
   private File statusDir;
@@ -86,7 +91,7 @@ class DescriptorQueue {
       directoryName = "exit-lists";
       break;
     default:
-      System.err.println("Unknown descriptor type.  Not adding directory "
+      log.error("Unknown descriptor type.  Not adding directory "
           + "to descriptor reader.");
       return;
     }
@@ -95,7 +100,7 @@ class DescriptorQueue {
       this.descriptorReader.addDirectory(directory);
       this.descriptorReader.setMaxDescriptorFilesInQueue(1);
     } else {
-      System.err.println("Directory " + directory.getAbsolutePath()
+      log.error("Directory " + directory.getAbsolutePath()
           + " either does not exist or is not a directory.  Not adding "
           + "to descriptor reader.");
     }
@@ -129,7 +134,7 @@ class DescriptorQueue {
       historyFileName = "bridge-server-history";
       break;
     default:
-      System.err.println("Unknown descriptor history.  Not excluding "
+      log.error("Unknown descriptor history.  Not excluding "
           + "files.");
       return;
     }
@@ -145,16 +150,15 @@ class DescriptorQueue {
             String[] parts = line.split(" ", 2);
             excludedFiles.put(parts[1], Long.parseLong(parts[0]));
           } catch (NumberFormatException e) {
-            System.err.println("Illegal line '" + line + "' in parse "
+            log.error("Illegal line '" + line + "' in parse "
                 + "history.  Skipping line.");
           }
         }
         br.close();
       } catch (IOException e) {
-        System.err.println("Could not read history file '"
+        log.error("Could not read history file '"
             + this.historyFile.getAbsolutePath() + "'.  Not excluding "
-            + "descriptors in this execution.");
-        e.printStackTrace();
+            + "descriptors in this execution.", e);
         return;
       }
       this.historySizeBefore = excludedFiles.size();
@@ -184,7 +188,7 @@ class DescriptorQueue {
       }
       bw.close();
     } catch (IOException e) {
-      System.err.println("Could not write history file '"
+      log.error("Could not write history file '"
           + this.historyFile.getAbsolutePath() + "'.  Not excluding "
           + "descriptors in next execution.");
       return;
@@ -199,9 +203,8 @@ class DescriptorQueue {
     while (this.descriptors == null && this.descriptorFiles.hasNext()) {
       DescriptorFile descriptorFile = this.descriptorFiles.next();
       if (descriptorFile.getException() != null) {
-        System.err.println("Could not parse "
-            + descriptorFile.getFileName());
-        descriptorFile.getException().printStackTrace();
+        log.error("Could not parse " + descriptorFile.getFileName(), 
+            descriptorFile.getException());
       }
       if (descriptorFile.getDescriptors() != null &&
           !descriptorFile.getDescriptors().isEmpty()) {
@@ -218,4 +221,4 @@ class DescriptorQueue {
     }
     return nextDescriptor;
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java b/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java
index ea1474f..644f503 100644
--- a/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java
+++ b/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java
@@ -12,6 +12,8 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.descriptor.BridgeNetworkStatus;
 import org.torproject.descriptor.BridgePoolAssignment;
 import org.torproject.descriptor.Descriptor;
@@ -20,10 +22,13 @@ import org.torproject.descriptor.ExitListEntry;
 import org.torproject.descriptor.ExtraInfoDescriptor;
 import org.torproject.descriptor.RelayNetworkStatusConsensus;
 import org.torproject.descriptor.ServerDescriptor;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 
 public class DescriptorSource {
 
+  private static final Logger log = LoggerFactory.getLogger(
+      DescriptorSource.class);
+
   private final File inDir = new File("in/recent");
 
   private final File statusDir = new File("status");
@@ -77,6 +82,7 @@ public class DescriptorSource {
 
   public void downloadDescriptors() {
     for (DescriptorType descriptorType : DescriptorType.values()) {
+      log.info("Loading: " + descriptorType);
       this.downloadDescriptors(descriptorType);
     }
   }
@@ -101,20 +107,32 @@ public class DescriptorSource {
   public void readDescriptors() {
     /* Careful when changing the order of parsing descriptor types!  The
      * various status updaters may base assumptions on this order. */
+
+    log.debug("Reading " + DescriptorType.RELAY_SERVER_DESCRIPTORS
+        + " ...");
     this.readDescriptors(DescriptorType.RELAY_SERVER_DESCRIPTORS,
         DescriptorHistory.RELAY_SERVER_HISTORY, true);
+    log.debug("Reading " + DescriptorType.RELAY_EXTRA_INFOS + " ...");
     this.readDescriptors(DescriptorType.RELAY_EXTRA_INFOS,
         DescriptorHistory.RELAY_EXTRAINFO_HISTORY, true);
+    log.debug("Reading " + DescriptorType.EXIT_LISTS + " ...");
     this.readDescriptors(DescriptorType.EXIT_LISTS,
         DescriptorHistory.EXIT_LIST_HISTORY, true);
+    log.debug("Reading " + DescriptorType.RELAY_CONSENSUSES + " ...");
     this.readDescriptors(DescriptorType.RELAY_CONSENSUSES,
         DescriptorHistory.RELAY_CONSENSUS_HISTORY, true);
+    log.debug("Reading " + DescriptorType.BRIDGE_SERVER_DESCRIPTORS
+        + " ...");
     this.readDescriptors(DescriptorType.BRIDGE_SERVER_DESCRIPTORS,
         DescriptorHistory.BRIDGE_SERVER_HISTORY, false);
+    log.debug("Reading " + DescriptorType.BRIDGE_EXTRA_INFOS + " ...");
     this.readDescriptors(DescriptorType.BRIDGE_EXTRA_INFOS,
         DescriptorHistory.BRIDGE_EXTRAINFO_HISTORY, false);
+    log.debug("Reading " + DescriptorType.BRIDGE_POOL_ASSIGNMENTS
+        + " ...");
     this.readDescriptors(DescriptorType.BRIDGE_POOL_ASSIGNMENTS,
         DescriptorHistory.BRIDGE_POOLASSIGN_HISTORY, false);
+    log.debug("Reading " + DescriptorType.BRIDGE_STATUSES + " ...");
     this.readDescriptors(DescriptorType.BRIDGE_STATUSES,
         DescriptorHistory.BRIDGE_STATUS_HISTORY, false);
   }
@@ -185,33 +203,34 @@ public class DescriptorSource {
     }
     switch (descriptorType) {
     case RELAY_CONSENSUSES:
-      Logger.printStatusTime("Read relay network consensuses");
+      log.info("Read relay network consensuses");
       break;
     case RELAY_SERVER_DESCRIPTORS:
-      Logger.printStatusTime("Read relay server descriptors");
+      log.info("Read relay server descriptors");
       break;
     case RELAY_EXTRA_INFOS:
-      Logger.printStatusTime("Read relay extra-info descriptors");
+      log.info("Read relay extra-info descriptors");
       break;
     case EXIT_LISTS:
-      Logger.printStatusTime("Read exit lists");
+      log.info("Read exit lists");
       break;
     case BRIDGE_STATUSES:
-      Logger.printStatusTime("Read bridge network statuses");
+      log.info("Read bridge network statuses");
       break;
     case BRIDGE_SERVER_DESCRIPTORS:
-      Logger.printStatusTime("Read bridge server descriptors");
+      log.info("Read bridge server descriptors");
       break;
     case BRIDGE_EXTRA_INFOS:
-      Logger.printStatusTime("Read bridge extra-info descriptors");
+      log.info("Read bridge extra-info descriptors");
       break;
     case BRIDGE_POOL_ASSIGNMENTS:
-      Logger.printStatusTime("Read bridge-pool assignments");
+      log.info("Read bridge-pool assignments");
       break;
     }
   }
 
   public void writeHistoryFiles() {
+    log.debug("Writing history ");
     for (DescriptorQueue descriptorQueue : this.descriptorQueues) {
       descriptorQueue.writeHistoryFile();
     }
@@ -237,13 +256,16 @@ public class DescriptorSource {
       descriptors += descriptorQueue.getReturnedDescriptors();
       bytes += descriptorQueue.getReturnedBytes();
     }
-    sb.append("    " + Logger.formatDecimalNumber(historySizeBefore)
-        + " descriptors excluded from this execution\n");
-    sb.append("    " + Logger.formatDecimalNumber(descriptors)
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        historySizeBefore) + " descriptors excluded from this "
+        + "execution\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(descriptors)
         + " descriptors provided\n");
-    sb.append("    " + Logger.formatBytes(bytes) + " provided\n");
-    sb.append("    " + Logger.formatDecimalNumber(historySizeAfter)
-        + " descriptors excluded from next execution\n");
+    sb.append("    " + FormattingUtils.formatBytes(bytes)
+        + " provided\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        historySizeAfter) + " descriptors excluded from next "
+        + "execution\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/updater/LookupService.java b/src/main/java/org/torproject/onionoo/updater/LookupService.java
index b816091..22560b2 100644
--- a/src/main/java/org/torproject/onionoo/updater/LookupService.java
+++ b/src/main/java/org/torproject/onionoo/updater/LookupService.java
@@ -17,10 +17,15 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.regex.Pattern;
 
-import org.torproject.onionoo.util.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.torproject.onionoo.util.FormattingUtils;
 
 public class LookupService {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      LookupService.class);
+
   private File geoipDir;
   private File geoLite2CityBlocksCsvFile;
   private File geoLite2CityLocationsCsvFile;
@@ -36,19 +41,19 @@ public class LookupService {
     this.geoLite2CityBlocksCsvFile = new File(this.geoipDir,
         "GeoLite2-City-Blocks.csv");
     if (!this.geoLite2CityBlocksCsvFile.exists()) {
-      System.err.println("No GeoLite2-City-Blocks.csv file in geoip/.");
+      log.error("No GeoLite2-City-Blocks.csv file in geoip/.");
       return;
     }
     this.geoLite2CityLocationsCsvFile = new File(this.geoipDir,
         "GeoLite2-City-Locations.csv");
     if (!this.geoLite2CityLocationsCsvFile.exists()) {
-      System.err.println("No GeoLite2-City-Locations.csv file in "
+      log.error("No GeoLite2-City-Locations.csv file in "
           + "geoip/.");
       return;
     }
     this.geoIPASNum2CsvFile = new File(this.geoipDir, "GeoIPASNum2.csv");
     if (!this.geoIPASNum2CsvFile.exists()) {
-      System.err.println("No GeoIPASNum2.csv file in geoip/.");
+      log.error("No GeoIPASNum2.csv file in geoip/.");
       return;
     }
     this.hasAllFiles = true;
@@ -119,7 +124,7 @@ public class LookupService {
         }
         String[] parts = line.replaceAll("\"", "").split(",", 10);
         if (parts.length != 10) {
-          System.err.println("Illegal line '" + line + "' in "
+          log.error("Illegal line '" + line + "' in "
               + geoLite2CityBlocksCsvFile.getAbsolutePath() + ".");
           br.close();
           return lookupResults;
@@ -128,7 +133,7 @@ public class LookupService {
           String startAddressString = parts[0].substring(7); /* ::ffff: */
           long startIpNum = this.parseAddressString(startAddressString);
           if (startIpNum < 0L) {
-            System.err.println("Illegal IP address in '" + line
+            log.error("Illegal IP address in '" + line
                 + "' in " + geoLite2CityBlocksCsvFile.getAbsolutePath()
                 + ".");
             br.close();
@@ -136,7 +141,7 @@ public class LookupService {
           }
           int networkMaskLength = Integer.parseInt(parts[1]);
           if (networkMaskLength < 96 || networkMaskLength > 128) {
-            System.err.println("Illegal network mask in '" + line
+            log.error("Illegal network mask in '" + line
                 + "' in " + geoLite2CityBlocksCsvFile.getAbsolutePath()
                 + ".");
             br.close();
@@ -160,7 +165,7 @@ public class LookupService {
             }
           }
         } catch (NumberFormatException e) {
-          System.err.println("Number format exception while parsing line "
+          log.error("Number format exception while parsing line "
               + "'" + line + "' in "
               + geoLite2CityBlocksCsvFile.getAbsolutePath() + ".");
           br.close();
@@ -169,7 +174,7 @@ public class LookupService {
       }
       br.close();
     } catch (IOException e) {
-      System.err.println("I/O exception while reading "
+      log.error("I/O exception while reading "
           + geoLite2CityBlocksCsvFile.getAbsolutePath() + ".");
       return lookupResults;
     }
@@ -186,7 +191,7 @@ public class LookupService {
       while ((line = br.readLine()) != null) {
         String[] parts = line.replaceAll("\"", "").split(",", 10);
         if (parts.length != 10) {
-          System.err.println("Illegal line '" + line + "' in "
+          log.error("Illegal line '" + line + "' in "
               + geoLite2CityLocationsCsvFile.getAbsolutePath() + ".");
           br.close();
           return lookupResults;
@@ -197,7 +202,7 @@ public class LookupService {
             blockLocations.put(locId, line);
           }
         } catch (NumberFormatException e) {
-          System.err.println("Number format exception while parsing line "
+          log.error("Number format exception while parsing line "
               + "'" + line + "' in "
               + geoLite2CityLocationsCsvFile.getAbsolutePath() + ".");
           br.close();
@@ -206,7 +211,7 @@ public class LookupService {
       }
       br.close();
     } catch (IOException e) {
-      System.err.println("I/O exception while reading "
+      log.error("I/O exception while reading "
           + geoLite2CityLocationsCsvFile.getAbsolutePath() + ".");
       return lookupResults;
     }
@@ -224,7 +229,7 @@ public class LookupService {
       while ((line = br.readLine()) != null) {
         String[] parts = line.replaceAll("\"", "").split(",", 3);
         if (parts.length != 3) {
-          System.err.println("Illegal line '" + line + "' in "
+          log.error("Illegal line '" + line + "' in "
               + geoIPASNum2CsvFile.getAbsolutePath() + ".");
           br.close();
           return lookupResults;
@@ -232,7 +237,7 @@ public class LookupService {
         try {
           long startIpNum = Long.parseLong(parts[0]);
           if (startIpNum <= previousStartIpNum) {
-            System.err.println("Line '" + line + "' not sorted in "
+            log.error("Line '" + line + "' not sorted in "
                 + geoIPASNum2CsvFile.getAbsolutePath() + ".");
             br.close();
             return lookupResults;
@@ -264,9 +269,8 @@ public class LookupService {
           if (firstAddressNumber == -1L) {
             break;
           }
-        }
-        catch (NumberFormatException e) {
-          System.err.println("Number format exception while parsing line "
+        } catch (NumberFormatException e) {
+          log.error("Number format exception while parsing line "
               + "'" + line + "' in "
               + geoIPASNum2CsvFile.getAbsolutePath() + ".");
           br.close();
@@ -275,7 +279,7 @@ public class LookupService {
       }
       br.close();
     } catch (IOException e) {
-      System.err.println("I/O exception while reading "
+      log.error("I/O exception while reading "
           + geoIPASNum2CsvFile.getAbsolutePath() + ".");
       return lookupResults;
     }
@@ -334,10 +338,10 @@ public class LookupService {
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(addressesLookedUp)
-        + " addresses looked up\n");
-    sb.append("    " + Logger.formatDecimalNumber(addressesResolved)
-        + " addresses resolved\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        addressesLookedUp) + " addresses looked up\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        addressesResolved) + " addresses resolved\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java b/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java
index 6341afd..f09a46c 100644
--- a/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java
+++ b/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java
@@ -13,6 +13,8 @@ import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.descriptor.BridgeNetworkStatus;
 import org.torproject.descriptor.BridgePoolAssignment;
 import org.torproject.descriptor.Descriptor;
@@ -26,12 +28,15 @@ import org.torproject.onionoo.docs.DetailsStatus;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.NodeStatus;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class NodeDetailsStatusUpdater implements DescriptorListener,
     StatusUpdater {
 
+  private Logger log = LoggerFactory.getLogger(
+      NodeDetailsStatusUpdater.class);
+
   private DescriptorSource descriptorSource;
 
   private ReverseDomainNameResolver reverseDomainNameResolver;
@@ -288,23 +293,23 @@ public class NodeDetailsStatusUpdater implements DescriptorListener,
 
   public void updateStatuses() {
     this.readStatusSummary();
-    Logger.printStatusTime("Read status summary");
+    log.info("Read status summary");
     this.setCurrentNodes();
-    Logger.printStatusTime("Set current node fingerprints");
+    log.info("Set current node fingerprints");
     this.startReverseDomainNameLookups();
-    Logger.printStatusTime("Started reverse domain name lookups");
+    log.info("Started reverse domain name lookups");
     this.lookUpCitiesAndASes();
-    Logger.printStatusTime("Looked up cities and ASes");
+    log.info("Looked up cities and ASes");
     this.setDescriptorPartsOfNodeStatus();
-    Logger.printStatusTime("Set descriptor parts of node statuses.");
+    log.info("Set descriptor parts of node statuses.");
     this.calculatePathSelectionProbabilities();
-    Logger.printStatusTime("Calculated path selection probabilities");
+    log.info("Calculated path selection probabilities");
     this.finishReverseDomainNameLookups();
-    Logger.printStatusTime("Finished reverse domain name lookups");
+    log.info("Finished reverse domain name lookups");
     this.writeStatusSummary();
-    Logger.printStatusTime("Wrote status summary");
+    log.info("Wrote status summary");
     this.updateDetailsStatuses();
-    Logger.printStatusTime("Updated exit addresses in details statuses");
+    log.info("Updated exit addresses in details statuses");
   }
 
   private void readStatusSummary() {
@@ -368,7 +373,7 @@ public class NodeDetailsStatusUpdater implements DescriptorListener,
       }
     }
     if (addressStrings.isEmpty()) {
-      System.err.println("No relay IP addresses to resolve to cities or "
+      log.error("No relay IP addresses to resolve to cities or "
           + "ASN.");
       return;
     }
@@ -456,7 +461,7 @@ public class NodeDetailsStatusUpdater implements DescriptorListener,
         wed = ((double) this.lastBandwidthWeights.get("Wed")) / 10000.0;
       }
     } else {
-      System.err.println("Could not determine most recent Wxx parameter "
+      log.error("Could not determine most recent Wxx parameter "
           + "values, probably because we didn't parse a consensus in "
           + "this execution.  All relays' guard/middle/exit weights are "
           + "going to be 0.0.");
@@ -609,10 +614,10 @@ public class NodeDetailsStatusUpdater implements DescriptorListener,
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
         relayConsensusesProcessed) + " relay consensuses processed\n");
-    sb.append("    " + Logger.formatDecimalNumber(bridgeStatusesProcessed)
-        + " bridge statuses processed\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        bridgeStatusesProcessed) + " bridge statuses processed\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/updater/ReverseDomainNameResolver.java b/src/main/java/org/torproject/onionoo/updater/ReverseDomainNameResolver.java
index dc662a5..681a681 100644
--- a/src/main/java/org/torproject/onionoo/updater/ReverseDomainNameResolver.java
+++ b/src/main/java/org/torproject/onionoo/updater/ReverseDomainNameResolver.java
@@ -10,7 +10,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 import org.torproject.onionoo.util.Time;
 import org.torproject.onionoo.util.TimeFactory;
 
@@ -88,16 +88,18 @@ public class ReverseDomainNameResolver {
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(rdnsLookupMillis.size())
-        + " lookups performed\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        rdnsLookupMillis.size()) + " lookups performed\n");
     if (rdnsLookupMillis.size() > 0) {
       Collections.sort(rdnsLookupMillis);
-      sb.append("    " + Logger.formatMillis(rdnsLookupMillis.get(0))
-          + " minimum lookup time\n");
-      sb.append("    " + Logger.formatMillis(rdnsLookupMillis.get(
-          rdnsLookupMillis.size() / 2)) + " median lookup time\n");
-      sb.append("    " + Logger.formatMillis(rdnsLookupMillis.get(
-          rdnsLookupMillis.size() - 1)) + " maximum lookup time\n");
+      sb.append("    " + FormattingUtils.formatMillis(
+          rdnsLookupMillis.get(0)) + " minimum lookup time\n");
+      sb.append("    " + FormattingUtils.formatMillis(
+          rdnsLookupMillis.get(rdnsLookupMillis.size() / 2))
+          + " median lookup time\n");
+      sb.append("    " + FormattingUtils.formatMillis(
+          rdnsLookupMillis.get(rdnsLookupMillis.size() - 1))
+          + " maximum lookup time\n");
     }
     return sb.toString();
   }
diff --git a/src/main/java/org/torproject/onionoo/updater/StatusUpdateRunner.java b/src/main/java/org/torproject/onionoo/updater/StatusUpdateRunner.java
index 09dd952..2080697 100644
--- a/src/main/java/org/torproject/onionoo/updater/StatusUpdateRunner.java
+++ b/src/main/java/org/torproject/onionoo/updater/StatusUpdateRunner.java
@@ -4,10 +4,14 @@ package org.torproject.onionoo.updater;
 
 import java.io.File;
 
-import org.torproject.onionoo.util.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class StatusUpdateRunner {
 
+  private static final Logger log = LoggerFactory.getLogger(
+      StatusUpdateRunner.class);
+
   private LookupService ls;
 
   private ReverseDomainNameResolver rdnr;
@@ -29,8 +33,9 @@ public class StatusUpdateRunner {
 
   public void updateStatuses() {
     for (StatusUpdater su : this.statusUpdaters) {
+      log.debug("Begin update of " + su.getClass().getSimpleName());
       su.updateStatuses();
-      Logger.printStatusTime(su.getClass().getSimpleName()
+      log.info(su.getClass().getSimpleName()
           + " updated status files");
     }
   }
@@ -39,13 +44,13 @@ public class StatusUpdateRunner {
     for (StatusUpdater su : this.statusUpdaters) {
       String statsString = su.getStatsString();
       if (statsString != null) {
-        Logger.printStatistics(su.getClass().getSimpleName(),
-            statsString);
+        LoggerFactory.getLogger("statistics").info(
+            su.getClass().getSimpleName(), statsString);
       }
     }
-    Logger.printStatistics("GeoIP lookup service",
+    LoggerFactory.getLogger("statistics").info("GeoIP lookup service",
         this.ls.getStatsString());
-    Logger.printStatistics("Reverse domain name resolver",
-        this.rdnr.getStatsString());
+    LoggerFactory.getLogger("statistics").info("Reverse domain name "
+        + "resolver", this.rdnr.getStatsString());
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/updater/UptimeStatusUpdater.java b/src/main/java/org/torproject/onionoo/updater/UptimeStatusUpdater.java
index 4bbdcf1..c3c98ed 100644
--- a/src/main/java/org/torproject/onionoo/updater/UptimeStatusUpdater.java
+++ b/src/main/java/org/torproject/onionoo/updater/UptimeStatusUpdater.java
@@ -16,7 +16,7 @@ import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.UptimeStatus;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 
 public class UptimeStatusUpdater implements DescriptorListener,
     StatusUpdater {
@@ -133,13 +133,13 @@ public class UptimeStatusUpdater implements DescriptorListener,
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
             this.newRelayStatuses.size()) + " hours of relay uptimes "
             + "processed\n");
-    sb.append("    " + Logger.formatDecimalNumber(
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
         this.newBridgeStatuses.size()) + " hours of bridge uptimes "
         + "processed\n");
-    sb.append("    " + Logger.formatDecimalNumber(
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
         this.newRunningRelays.size() + this.newRunningBridges.size())
         + " uptime status files updated\n");
     return sb.toString();
diff --git a/src/main/java/org/torproject/onionoo/util/FormattingUtils.java b/src/main/java/org/torproject/onionoo/util/FormattingUtils.java
new file mode 100644
index 0000000..bda5a1d
--- /dev/null
+++ b/src/main/java/org/torproject/onionoo/util/FormattingUtils.java
@@ -0,0 +1,31 @@
+/* Copyright 2013 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.onionoo.util;
+
+public class FormattingUtils {
+
+  private FormattingUtils() {
+  }
+
+  private static final long ONE_SECOND = 1000L,
+      ONE_MINUTE = 60L * ONE_SECOND;
+
+  public static String formatMillis(long millis) {
+    return String.format("%02d:%02d.%03d minutes", millis / ONE_MINUTE,
+        (millis % ONE_MINUTE) / ONE_SECOND, millis % ONE_SECOND);
+  }
+
+  public static String formatBytes(long bytes) {
+    if (bytes < 1024) {
+      return bytes + " B";
+    } else {
+      int exp = (int) (Math.log(bytes) / Math.log(1024));
+      return String.format("%.1f %siB", bytes / Math.pow(1024, exp),
+          "KMGTPE".charAt(exp - 1));
+    }
+  }
+
+  public static String formatDecimalNumber(long decimalNumber) {
+    return String.format("%,d", decimalNumber);
+  }
+}
diff --git a/src/main/java/org/torproject/onionoo/util/LockFile.java b/src/main/java/org/torproject/onionoo/util/LockFile.java
index 9c6b723..0a1f17d 100644
--- a/src/main/java/org/torproject/onionoo/util/LockFile.java
+++ b/src/main/java/org/torproject/onionoo/util/LockFile.java
@@ -7,8 +7,14 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class LockFile {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      LockFile.class);
+
   private final File lockFile = new File("lock");
 
   public boolean acquireLock() {
@@ -26,9 +32,7 @@ public class LockFile {
       bw.close();
       return true;
     } catch (IOException e) {
-      System.err.println("Caught exception while trying to acquire "
-          + "lock!");
-      e.printStackTrace();
+      log.error("Caught exception while trying to acquire lock!", e);
       return false;
     }
   }
diff --git a/src/main/java/org/torproject/onionoo/util/Logger.java b/src/main/java/org/torproject/onionoo/util/Logger.java
deleted file mode 100644
index a9c7cde..0000000
--- a/src/main/java/org/torproject/onionoo/util/Logger.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright 2013 The Tor Project
- * See LICENSE for licensing information */
-package org.torproject.onionoo.util;
-
-import java.util.Date;
-
-public class Logger {
-
-  private Logger() {
-  }
-
-  private static Time time;
-
-  public static void setTime() {
-    time = TimeFactory.getTime();
-  }
-
-  private static long currentTimeMillis() {
-    if (time == null) {
-      return System.currentTimeMillis();
-    } else {
-      return time.currentTimeMillis();
-    }
-  }
-
-  public static String formatDecimalNumber(long decimalNumber) {
-    return String.format("%,d", decimalNumber);
-  }
-
-  private static final long ONE_SECOND = 1000L,
-      ONE_MINUTE = 60L * ONE_SECOND;
-
-  public static String formatMillis(long millis) {
-    return String.format("%02d:%02d.%03d minutes", millis / ONE_MINUTE,
-        (millis % ONE_MINUTE) / ONE_SECOND, millis % ONE_SECOND);
-  }
-
-  public static String formatBytes(long bytes) {
-    if (bytes < 1024) {
-      return bytes + " B";
-    } else {
-      int exp = (int) (Math.log(bytes) / Math.log(1024));
-      return String.format("%.1f %siB", bytes / Math.pow(1024, exp),
-          "KMGTPE".charAt(exp-1));
-    }
-  }
-
-  private static long printedLastStatusMessage = -1L;
-
-  public static void printStatus(String message) {
-    System.out.println(new Date() + ": " + message);
-    printedLastStatusMessage = currentTimeMillis();
-  }
-
-  public static void printStatistics(String component, String message) {
-    System.out.print("  " + component + " statistics:\n" + message);
-  }
-
-  public static void printStatusTime(String message) {
-    printStatusOrErrorTime(message, false);
-  }
-
-  public static void printErrorTime(String message) {
-    printStatusOrErrorTime(message, true);
-  }
-
-  private static void printStatusOrErrorTime(String message,
-      boolean printToSystemErr) {
-    long now = currentTimeMillis();
-    long millis = printedLastStatusMessage < 0 ? 0 :
-        now - printedLastStatusMessage;
-    String line = "  " + message + " (" + Logger.formatMillis(millis)
-        + ").";
-    if (printToSystemErr) {
-      System.err.println(line);
-    } else {
-      System.out.println(line);
-    }
-    printedLastStatusMessage = now;
-  }
-}
-
diff --git a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index f5d860c..c5167d0 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -11,6 +11,8 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.BandwidthDocument;
 import org.torproject.onionoo.docs.BandwidthStatus;
 import org.torproject.onionoo.docs.DateTimeHelper;
@@ -21,12 +23,14 @@ import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.DescriptorType;
 import org.torproject.onionoo.updater.FingerprintListener;
-import org.torproject.onionoo.util.Logger;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class BandwidthDocumentWriter implements FingerprintListener,
     DocumentWriter{
 
+  private static final Logger log = LoggerFactory.getLogger(
+      BandwidthDocumentWriter.class);
+
   private DescriptorSource descriptorSource;
 
   private DocumentStore documentStore;
@@ -65,7 +69,7 @@ public class BandwidthDocumentWriter implements FingerprintListener,
           fingerprint, bandwidthStatus);
       this.documentStore.store(bandwidthDocument, fingerprint);
     }
-    Logger.printStatusTime("Wrote bandwidth document files");
+    log.info("Wrote bandwidth document files");
   }
 
 
diff --git a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 0541be8..4086bc7 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -11,6 +11,8 @@ import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.ClientsDocument;
 import org.torproject.onionoo.docs.ClientsGraphHistory;
 import org.torproject.onionoo.docs.ClientsHistory;
@@ -22,7 +24,7 @@ import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.DescriptorType;
 import org.torproject.onionoo.updater.FingerprintListener;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 import org.torproject.onionoo.util.TimeFactory;
 
 /*
@@ -51,6 +53,9 @@ import org.torproject.onionoo.util.TimeFactory;
 public class ClientsDocumentWriter implements FingerprintListener,
     DocumentWriter {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      ClientsDocumentWriter.class);
+
   private DescriptorSource descriptorSource;
 
   private DocumentStore documentStore;
@@ -93,7 +98,7 @@ public class ClientsDocumentWriter implements FingerprintListener,
       this.documentStore.store(clientsDocument, hashedFingerprint);
       this.writtenDocuments++;
     }
-    Logger.printStatusTime("Wrote clients document files");
+    log.info("Wrote clients document files");
   }
 
   private String[] graphNames = new String[] {
@@ -291,8 +296,8 @@ public class ClientsDocumentWriter implements FingerprintListener,
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(this.writtenDocuments)
-        + " clients document files updated\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        this.writtenDocuments) + " clients document files updated\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
index bd2a955..3e6b07f 100644
--- a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
@@ -8,6 +8,8 @@ import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DetailsDocument;
 import org.torproject.onionoo.docs.DetailsStatus;
@@ -18,12 +20,14 @@ import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.DescriptorType;
 import org.torproject.onionoo.updater.FingerprintListener;
-import org.torproject.onionoo.util.Logger;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class DetailsDocumentWriter implements FingerprintListener,
     DocumentWriter {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      DetailsDocumentWriter.class);
+
   private DescriptorSource descriptorSource;
 
   private DocumentStore documentStore;
@@ -67,7 +71,7 @@ public class DetailsDocumentWriter implements FingerprintListener,
   public void writeDocuments() {
     this.updateRelayDetailsFiles();
     this.updateBridgeDetailsFiles();
-    Logger.printStatusTime("Wrote details document files");
+    log.info("Wrote details document files");
   }
 
   private void updateRelayDetailsFiles() {
diff --git a/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java b/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
index 559206f..dbca06e 100644
--- a/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
+++ b/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
@@ -2,10 +2,14 @@
  * See LICENSE for licensing information */
 package org.torproject.onionoo.writer;
 
-import org.torproject.onionoo.util.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DocumentWriterRunner {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      DocumentWriterRunner.class);
+
   private DocumentWriter[] documentWriters;
 
   public DocumentWriterRunner() {
@@ -21,6 +25,7 @@ public class DocumentWriterRunner {
 
   public void writeDocuments() {
     for (DocumentWriter dw : this.documentWriters) {
+      log.debug("Writing " + dw.getClass().getSimpleName());
       dw.writeDocuments();
     }
   }
@@ -29,7 +34,7 @@ public class DocumentWriterRunner {
     for (DocumentWriter dw : this.documentWriters) {
       String statsString = dw.getStatsString();
       if (statsString != null) {
-        Logger.printStatistics(dw.getClass().getSimpleName(),
+        log.info(dw.getClass().getSimpleName(),
             statsString);
       }
     }
diff --git a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
index 8d68dea..d7686cb 100644
--- a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
@@ -6,15 +6,20 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.SortedSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.NodeStatus;
 import org.torproject.onionoo.docs.SummaryDocument;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 
 public class SummaryDocumentWriter implements DocumentWriter {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      SummaryDocumentWriter.class);
+
   private DocumentStore documentStore;
 
   public SummaryDocumentWriter() {
@@ -80,15 +85,15 @@ public class SummaryDocumentWriter implements DocumentWriter {
         this.writtenDocuments++;
       };
     }
-    Logger.printStatusTime("Wrote summary document files");
+    log.info("Wrote summary document files");
   }
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(this.writtenDocuments)
-        + " summary document files written\n");
-    sb.append("    " + Logger.formatDecimalNumber(this.deletedDocuments)
-        + " summary document files deleted\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        this.writtenDocuments) + " summary document files written\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        this.deletedDocuments) + " summary document files deleted\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
index 92b434a..973fa67 100644
--- a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
@@ -9,6 +9,8 @@ import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
@@ -20,12 +22,15 @@ import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.DescriptorType;
 import org.torproject.onionoo.updater.FingerprintListener;
-import org.torproject.onionoo.util.Logger;
+import org.torproject.onionoo.util.FormattingUtils;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class UptimeDocumentWriter implements FingerprintListener,
     DocumentWriter {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      UptimeDocumentWriter.class);
+
   private DescriptorSource descriptorSource;
 
   private DocumentStore documentStore;
@@ -72,7 +77,7 @@ public class UptimeDocumentWriter implements FingerprintListener,
       this.updateDocument(false, fingerprint,
           uptimeStatus.getBridgeHistory());
     }
-    Logger.printStatusTime("Wrote uptime document files");
+    log.info("Wrote uptime document files");
   }
 
   private int writtenDocuments = 0;
@@ -297,8 +302,8 @@ public class UptimeDocumentWriter implements FingerprintListener,
 
   public String getStatsString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("    " + Logger.formatDecimalNumber(this.writtenDocuments)
-        + " uptime document files written\n");
+    sb.append("    " + FormattingUtils.formatDecimalNumber(
+        this.writtenDocuments) + " uptime document files written\n");
     return sb.toString();
   }
 }
diff --git a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index 9af9825..0d70465 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -11,6 +11,8 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
@@ -21,12 +23,14 @@ import org.torproject.onionoo.updater.DescriptorSource;
 import org.torproject.onionoo.updater.DescriptorSourceFactory;
 import org.torproject.onionoo.updater.DescriptorType;
 import org.torproject.onionoo.updater.FingerprintListener;
-import org.torproject.onionoo.util.Logger;
 import org.torproject.onionoo.util.TimeFactory;
 
 public class WeightsDocumentWriter implements FingerprintListener,
     DocumentWriter {
 
+  private final static Logger log = LoggerFactory.getLogger(
+      WeightsDocumentWriter.class);
+
   private DescriptorSource descriptorSource;
 
   private DocumentStore documentStore;
@@ -58,7 +62,7 @@ public class WeightsDocumentWriter implements FingerprintListener,
 
   public void writeDocuments() {
     this.writeWeightsDataFiles();
-    Logger.printStatusTime("Wrote weights document files");
+    log.info("Wrote weights document files");
   }
 
   private void writeWeightsDataFiles() {
@@ -73,7 +77,7 @@ public class WeightsDocumentWriter implements FingerprintListener,
           fingerprint, history);
       this.documentStore.store(weightsDocument, fingerprint);
     }
-    Logger.printStatusTime("Wrote weights document files");
+    log.info("Wrote weights document files");
   }
 
   private String[] graphNames = new String[] {



More information about the tor-commits mailing list