diff --git a/runtime/Logger.cpp b/runtime/Logger.cpp
new file mode 100644
index 0000000..11a4e44
--- /dev/null
+++ b/runtime/Logger.cpp
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// Logger.cpp - Logger Utility
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "pgAdmin4.h"
+#include "Logger.h"
+Logger* Logger::m_pThis = NULL;
+QString Logger::m_sFileName = "";
+QFile* Logger::m_Logfile = NULL;
+
+Logger::Logger()
+{
+}
+Logger::~Logger()
+{
+}
+
+Logger* Logger::GetLogger()
+{
+    if (m_pThis == NULL)
+    {
+        m_pThis = new Logger();
+        m_sFileName = QDir::homePath() + (QString("/%1_startup.log").arg(PGA_APP_NAME)).remove(" ");
+        m_Logfile = new QFile;
+        m_Logfile->setFileName(m_sFileName);
+        m_Logfile->open(QIODevice::WriteOnly | QIODevice::Text);
+    }
+
+    return m_pThis;
+}
+
+void Logger::Log(const QString& sMessage)
+{
+    QString text = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss ") + sMessage + "\n";
+    if (m_Logfile != NULL)
+    {
+        QTextStream out(m_Logfile);
+        out << text;
+    }
+}
+
+void Logger::ReleaseLogger()
+{
+    if (m_pThis != NULL)
+    {
+        if(m_Logfile != NULL)
+            m_Logfile->close();
+        delete m_pThis;
+        m_pThis = NULL;
+    }
+}
diff --git a/runtime/Logger.h b/runtime/Logger.h
new file mode 100644
index 0000000..f8ffba0
--- /dev/null
+++ b/runtime/Logger.h
@@ -0,0 +1,34 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// Logger.h - Logger Utility
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <QObject>
+
+class Logger : public QObject
+{
+public:
+    static Logger* GetLogger();
+    static void ReleaseLogger();
+    void Log(const QString& sMessage);
+
+private:
+    Logger();
+    virtual ~Logger();
+
+private:
+    static Logger* m_pThis;
+    static QString m_sFileName;
+    static QFile *m_Logfile;
+};
+
+#endif // LOGGER_H
diff --git a/runtime/Server.cpp b/runtime/Server.cpp
index bf7f0bc..aedb66f 100644
--- a/runtime/Server.cpp
+++ b/runtime/Server.cpp
@@ -10,6 +10,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 #include "pgAdmin4.h"
+#include "Logger.h"
 
 // Must be before QT
 #include <Python.h>
@@ -175,6 +176,10 @@ Server::Server(quint16 port, QString key, QString logFileName)
 
     qDebug() << "Python path: " << python_path
              << "\nPython Home: " << pythonHome;
+
+    Logger::GetLogger()->Log(QString("Python Path: %1").arg(python_path));
+    Logger::GetLogger()->Log(QString("Python Home: %1").arg(pythonHome));
+
     if (!pythonHome.isEmpty())
     {
         pythonHome_utf8 = pythonHome.toUtf8();
@@ -190,12 +195,15 @@ Server::Server(quint16 port, QString key, QString logFileName)
 #endif
     }
 
+    Logger::GetLogger()->Log("Initializing Python...");
     Py_Initialize();
+    Logger::GetLogger()->Log("Python initialized.");
 
     // Get the current path
     PyObject* sysPath = PySys_GetObject((char*)"path");
 
     // Add new additional path elements
+    Logger::GetLogger()->Log("Adding new additional path elements");
     for (i = path_list.size() - 1; i >= 0 ; --i)
     {
 #ifdef PYTHON2
@@ -210,6 +218,7 @@ Server::Server(quint16 port, QString key, QString logFileName)
     }
 
     // Redirect stderr
+    Logger::GetLogger()->Log("Redirecting stderr...");
     PyObject *sys = PyImport_ImportModule("sys");
 #ifdef PYTHON2
     PyObject *err = PyFile_FromString(m_logFileName.toUtf8().data(), (char *)"w");
@@ -263,12 +272,14 @@ bool Server::Init()
         if (QFile::exists(m_appfile))
         {
             qDebug() << "Webapp path: " << m_appfile;
+            Logger::GetLogger()->Log(QString("Webapp Path: %1").arg(m_appfile));
             break;
         }
     }
 
     if (!QFile::exists(m_appfile))
     {
+        Logger::GetLogger()->Log("Failed to locate pgAdmin4.py, terminating server thread.");
         setError(tr("Failed to locate pgAdmin4.py, terminating server thread."));
         return false;
     }
@@ -279,14 +290,17 @@ bool Server::Init()
 void Server::run()
 {
     // Open the application code and run it.
+    Logger::GetLogger()->Log("Open the application code and run it.");
     FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
     if (!cp)
     {
+        Logger::GetLogger()->Log(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
         setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
         return;
     }
 
     // Set the port number and key, and force SERVER_MODE off.
+    Logger::GetLogger()->Log("Set the port number and key, and force SERVER_MODE off");
     PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
     PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1());
     PyRun_SimpleString(QString("SERVER_MODE = False").toLatin1());
@@ -303,10 +317,14 @@ void Server::run()
     char* n_argv[] = { m_appfile_utf8.data() };
     PySys_SetArgv(1, n_argv);
 
+    Logger::GetLogger()->Log("Server::run: PyRun_SimpleFile launching application server...");
     PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
     int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
     if (ret != 0)
+    {
+        Logger::GetLogger()->Log("Failed to launch the application server, server thread exiting.");
         setError(tr("Failed to launch the application server, server thread exiting."));
+    }
 #else
     /*
      * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
@@ -321,8 +339,12 @@ void Server::run()
     wchar_t* n_argv[] = { wcAppName };
     PySys_SetArgv(1, n_argv);
 
+    Logger::GetLogger()->Log("Server::run: PyRun_SimpleFile launching application server...");
     if (PyRun_SimpleFile(cp, m_appfile_utf8.data()) != 0)
+    {
+        Logger::GetLogger()->Log("Failed to launch the application server, server thread exiting.");
         setError(tr("Failed to launch the application server, server thread exiting."));
+    }
 #endif
 
     fclose(cp);
diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
index a397b59..48c6263 100644
--- a/runtime/pgAdmin4.cpp
+++ b/runtime/pgAdmin4.cpp
@@ -36,6 +36,7 @@
 #include "TrayIcon.h"
 #include "MenuActions.h"
 #include "FloatingWindow.h"
+#include "Logger.h"
 
 #include <QTime>
 
@@ -217,6 +218,7 @@ int main(int argc, char * argv[])
         menuActions->setLogFile(logFileName);
 
     splash->showMessage(QString(QWidget::tr("Checking for system tray...")), Qt::AlignBottom | Qt::AlignCenter);
+    Logger::GetLogger()->Log("Checking for system tray...");
 
     // Check system tray is available or not. If not then create one floating window.
     FloatingWindow *floatingWindow = NULL;
@@ -235,13 +237,15 @@ int main(int argc, char * argv[])
     else
     {
         splash->showMessage(QString(QWidget::tr("System tray not found, creating floating window...")), Qt::AlignBottom | Qt::AlignCenter);
+        Logger::GetLogger()->Log("System tray not found, creating floating window...");
         // Unable to find tray icon, so creating floting window
         floatingWindow = new FloatingWindow();
         if (floatingWindow == NULL)
         {
             QString error = QString(QWidget::tr("Unable to initialize either a tray icon or control window."));
             QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
-
+            Logger::GetLogger()->Log(error);
+            Logger::ReleaseLogger();
             exit(1);
         }
 
@@ -256,8 +260,11 @@ int main(int argc, char * argv[])
     bool done = false;
 
     splash->showMessage(QString(QWidget::tr("Starting pgAdmin4 server...")), Qt::AlignBottom | Qt::AlignCenter);
+    Logger::GetLogger()->Log("Starting pgAdmin4 server...");
     while (done != true)
     {
+        QString msg = QString(QWidget::tr("Initializing server object, port:%1, key:%2, logfile:%3")).arg(port).arg(key).arg(logFileName);
+        Logger::GetLogger()->Log(msg);
         server = new Server(port, key, logFileName);
 
         if (!server->Init())
@@ -269,9 +276,13 @@ int main(int argc, char * argv[])
             QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
             QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
 
+            Logger::GetLogger()->Log(error);
+            Logger::ReleaseLogger();
+
             exit(1);
         }
 
+        Logger::GetLogger()->Log("Starting Server Thread...");
         server->start();
 
         // This is a hack to give the server a chance to start and potentially fail. As
@@ -290,6 +301,7 @@ int main(int argc, char * argv[])
 
             QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
             QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
+            Logger::GetLogger()->Log(error);
 
             // Allow the user to tweak the Python Path if needed
             bool ok;
@@ -315,6 +327,7 @@ int main(int argc, char * argv[])
             }
             else
             {
+                Logger::ReleaseLogger();
                 exit(1);
             }
 
@@ -329,6 +342,7 @@ int main(int argc, char * argv[])
 
     // Generate the app server URL
     QString appServerUrl = QString("http://127.0.0.1:%1/?key=%2").arg(port).arg(key);
+    Logger::GetLogger()->Log(QString(QWidget::tr("Application Server URL: %1")).arg(appServerUrl));
 
     // Read the server connection timeout from the registry or set the default timeout.
     int timeout = settings.value("ConnectionTimeout", 30).toInt();
@@ -339,6 +353,7 @@ int main(int argc, char * argv[])
     QTime endTime = QTime::currentTime().addSecs(timeout);
     bool alive = false;
 
+    Logger::GetLogger()->Log("The server should be up, we'll attempt to connect and get a response. Ping the server");
     while(QTime::currentTime() <= endTime)
     {
         alive = PingServer(QUrl(appServerUrl));
@@ -352,12 +367,14 @@ int main(int argc, char * argv[])
     }
 
     // Attempt to connect one more time in case of a long network timeout while looping
+    Logger::GetLogger()->Log("Attempt to connect one more time in case of a long network timeout while looping");
     if (!alive && !PingServer(QUrl(appServerUrl)))
     {
         splash->finish(NULL);
         QString error(QWidget::tr("The application server could not be contacted."));
         QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
 
+        Logger::ReleaseLogger();
         exit(1);
     }
 
@@ -392,6 +409,8 @@ int main(int argc, char * argv[])
             QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?."));
             QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
 
+            Logger::GetLogger()->Log(error);
+            Logger::ReleaseLogger();
             exit(1);
         }
     }
@@ -402,6 +421,8 @@ int main(int argc, char * argv[])
     if (floatingWindow != NULL)
         floatingWindow->show();
 
+    Logger::GetLogger()->Log("Everything works fine, successfully started pgAdmin4.");
+    Logger::ReleaseLogger();
     return app.exec();
 }
 
diff --git a/runtime/pgAdmin4.pro b/runtime/pgAdmin4.pro
index 2451782..21ebfbc 100644
--- a/runtime/pgAdmin4.pro
+++ b/runtime/pgAdmin4.pro
@@ -93,14 +93,16 @@ HEADERS     =   Server.h \
                 TrayIcon.h \
                 LogWindow.h \
                 MenuActions.h \
-                FloatingWindow.h
+                FloatingWindow.h \
+                Logger.h
 SOURCES     =   pgAdmin4.cpp \
                 Server.cpp \
                 ConfigWindow.cpp \
                 TrayIcon.cpp \
                 LogWindow.cpp \
                 MenuActions.cpp \
-                FloatingWindow.cpp
+                FloatingWindow.cpp \
+                Logger.cpp
 FORMS       =   ConfigWindow.ui \
                 LogWindow.ui \
                 FloatingWindow.ui
