--- a
+++ b/qiita_db/logger.py
@@ -0,0 +1,207 @@
+r"""
+Logging objects (:mod: `qiita_db.logger`)
+====================================
+
+..currentmodule:: qiita_db.logger
+
+This module provides objects for recording log information
+
+Classes
+-------
+
+..autosummary::
+    :toctree: generated/
+
+    LogEntry
+"""
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2014--, The Qiita Development Team.
+#
+# Distributed under the terms of the BSD 3-clause License.
+#
+# The full license is in the file LICENSE, distributed with this software.
+# -----------------------------------------------------------------------------
+from json import loads, dumps
+
+import qiita_db as qdb
+
+
+class LogEntry(qdb.base.QiitaObject):
+    """
+    Attributes
+    ----------
+    severity
+    time
+    info
+    msg
+
+    Methods
+    -------
+    clear_info
+    add_info
+    """
+
+    _table = 'logging'
+
+    @classmethod
+    def newest_records(cls, numrecords=100):
+        """Return a list of the newest records in the logging table
+
+        Parameters
+        ----------
+        numrecords : int, optional
+            The number of records to return. Default 100
+
+        Returns
+        -------
+        list of LogEntry objects
+            list of the log entries
+        """
+        with qdb.sql_connection.TRN:
+            sql = """SELECT logging_id
+                     FROM qiita.{0}
+                     ORDER BY logging_id DESC LIMIT %s""".format(cls._table)
+            qdb.sql_connection.TRN.add(sql, [numrecords])
+
+            return [cls(i)
+                    for i in qdb.sql_connection.TRN.execute_fetchflatten()]
+
+    @classmethod
+    def create(cls, severity, msg, info=None):
+        """Creates a new LogEntry object
+
+        Parameters
+        ----------
+        severity : str  {Warning, Runtime, Fatal}
+            The level of severity to use for the LogEntry. Refers to an entry
+            in the SEVERITY table.
+        msg : str
+            The message text
+        info : dict, optional
+            Defaults to ``None``. If supplied, the information will be added
+            as the first entry in a list of information dicts. If ``None``,
+            an empty dict will be added.
+
+        Notes
+        -----
+        - When `info` is added, keys can be of any type, but upon retrieval,
+          they will be of type str
+        """
+        if info is None:
+            info = {}
+
+        info = dumps([info])
+
+        with qdb.sql_connection.TRN:
+            sql = """INSERT INTO qiita.{} (time, severity_id, msg, information)
+                     VALUES (NOW(), %s, %s, %s)
+                     RETURNING logging_id""".format(cls._table)
+            severity_id = qdb.util.convert_to_id(severity, "severity")
+            qdb.sql_connection.TRN.add(sql, [severity_id, msg, info])
+
+            return cls(qdb.sql_connection.TRN.execute_fetchlast())
+
+    @property
+    def severity(self):
+        """Returns the severity_id associated with this LogEntry
+
+        Returns
+        -------
+        int
+            This is a key to the SEVERITY table
+        """
+        with qdb.sql_connection.TRN:
+            sql = """SELECT severity_id FROM qiita.{}
+                     WHERE logging_id = %s""".format(self._table)
+            qdb.sql_connection.TRN.add(sql, [self.id])
+            return qdb.sql_connection.TRN.execute_fetchlast()
+
+    @property
+    def time(self):
+        """Returns the time that this LogEntry was created
+
+        Returns
+        -------
+        datetime
+        """
+        with qdb.sql_connection.TRN:
+            sql = "SELECT time FROM qiita.{} WHERE logging_id = %s".format(
+                self._table)
+            qdb.sql_connection.TRN.add(sql, [self.id])
+
+            return qdb.sql_connection.TRN.execute_fetchlast()
+
+    @property
+    def info(self):
+        """Returns the info associated with this LogEntry
+
+        Returns
+        -------
+        list of dict
+            Each entry in the list is information that was added (the info
+            added upon creation will be index 0, and if additional info
+            was supplied subsequently, those entries will occupy subsequent
+            indices)
+
+        Notes
+        -----
+        - When `info` is added, keys can be of any type, but upon retrieval,
+          they will be of type str
+        """
+        with qdb.sql_connection.TRN:
+            sql = """SELECT information FROM qiita.{} WHERE
+                     logging_id = %s""".format(self._table)
+            qdb.sql_connection.TRN.add(sql, [self.id])
+
+            rows = qdb.sql_connection.TRN.execute_fetchlast()
+
+            if rows:
+                results = loads(rows)
+            else:
+                results = {}
+
+            return results
+
+    @property
+    def msg(self):
+        """Gets the message text for this LogEntry
+
+        Returns
+        -------
+        str
+        """
+        with qdb.sql_connection.TRN:
+            sql = "SELECT msg FROM qiita.{0} WHERE logging_id = %s".format(
+                self._table)
+            qdb.sql_connection.TRN.add(sql, [self.id])
+
+            return qdb.sql_connection.TRN.execute_fetchlast()
+
+    def clear_info(self):
+        """Resets the list of info dicts to be an empty list
+        """
+        sql = """UPDATE qiita.{} SET information = %s
+                 WHERE logging_id = %s""".format(self._table)
+        qdb.sql_connection.perform_as_transaction(sql, [dumps([]), self.id])
+
+    def add_info(self, info):
+        """Adds new information to the info associated with this LogEntry
+
+        Parameters
+        ----------
+        info : dict
+            The information to add.
+
+        Notes
+        -----
+        - When `info` is added, keys can be of any type, but upon retrieval,
+          they will be of type str
+        """
+        current_info = self.info
+        current_info.append(info)
+        new_info = dumps(current_info)
+
+        sql = """UPDATE qiita.{} SET information = %s
+                 WHERE logging_id = %s""".format(self._table)
+        qdb.sql_connection.perform_as_transaction(sql, [new_info, self.id])