diff --git a/.gitignore b/.gitignore
index 9eca034d61d74660f3cb2fe12292148b84f5e15c..1fca780f5c3f8f1e9b49800d437720d5a6397ea7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,8 @@ appointment-import/tmp.sql
 *.iml
 out
 .idea
+smash/smash.log
+
 
 .coverage
 smash/htmlcov/
diff --git a/smash/smash/local_settings.py.template b/smash/smash/local_settings.py.template
index bb8abb8c205e9b027f8af35341958a1cacc28274..652a544a7cbe0200a79bf08391d99e85743fc7fd 100644
--- a/smash/smash/local_settings.py.template
+++ b/smash/smash/local_settings.py.template
@@ -43,3 +43,39 @@ STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
 NEXMO_API_KEY = 'API_KEY'
 NEXMO_API_SECRET = 'API_SECRET'
 NEXMO_DEFAULT_FROM = 'Scheduling'  # the sender of the message (phone number or text)
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'handlers': {
+        'file': {
+            'level': 'INFO',
+            'class': 'logging.FileHandler',
+            'filename': 'smash.log',
+            'formatter': 'verbose'
+        },
+        'console': {
+            'class': 'logging.StreamHandler',
+            'level': 'WARNING',
+            'formatter': 'simple'
+        },
+    },
+    'formatters': {
+        'verbose': {
+            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
+        },
+        'simple': {
+            'format': '%(levelname)s %(message)s'
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['file'],
+            'level': 'INFO',
+        },
+        'web': {
+            'handlers': ['file', 'console'],
+            'level': 'INFO',
+        },
+    },
+}
diff --git a/smash/web/auth.py b/smash/web/auth.py
index 87e77838f1d9b84d28a661f1a0006adbefa9dc8b..6f81157c0adddfbcd1fe3394846b4b72f359f2a2 100644
--- a/smash/web/auth.py
+++ b/smash/web/auth.py
@@ -1,13 +1,21 @@
+import logging
+
 from django.contrib.auth import authenticate, login, logout
+from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
+from django.dispatch import receiver
+
+logger = logging.getLogger(__name__)
 
 
 def do_login(request):
-    user = authenticate(username=request.POST.get('username', 'none'),
+    user_login = request.POST.get('username', 'none')
+    user = authenticate(username=user_login,
                         password=request.POST.get('password', 'none'))
     if user is not None:
         login(request, user)
         return True, "ok"
-    return False, "login_failed"
+    else:
+        return False, "login_failed"
 
 
 def do_logout(request):
@@ -15,3 +23,33 @@ def do_logout(request):
         logout(request)
         return True, "logout"
     return False, "logout_failed"
+
+
+# code that put in logs every successful and problematic login/logout event
+# https://stackoverflow.com/questions/37618473/how-can-i-log-both-successful-and-failed-login-and-logout-attempts-in-django
+@receiver(user_logged_in)
+def user_logged_in_callback(sender, request, user, **kwargs):
+    # to cover more complex cases:
+    # http://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django
+    ip = request.META.get('REMOTE_ADDR')
+    logger.info('login user: {user} via ip: {ip}'.format(
+        user=user,
+        ip=ip
+    ))
+
+
+@receiver(user_logged_out)
+def user_logged_out_callback(sender, request, user, **kwargs):
+    ip = request.META.get('REMOTE_ADDR')
+
+    logger.info('logout user: {user} via ip: {ip}'.format(
+        user=user,
+        ip=ip
+    ))
+
+
+@receiver(user_login_failed)
+def user_login_failed_callback(sender, credentials, **kwargs):
+    logger.warning('login failed for: {credentials}'.format(
+        credentials=credentials,
+    ))
diff --git a/smash/web/smash_email.py b/smash/web/smash_email.py
index 51d54ba029b0851bc44847db3e471a972487bde5..882c39b4b732561dc34d779ba487d2f5913d66ef 100644
--- a/smash/web/smash_email.py
+++ b/smash/web/smash_email.py
@@ -1,8 +1,12 @@
 # coding=utf-8
 
+import logging
+
 from django.conf import settings
 from django.core.mail import EmailMessage
 
+logger = logging.getLogger(__name__)
+
 
 class EmailSender(object):
     def send_email(self, subject, body, recipients, cc_recipients=None):
@@ -23,5 +27,4 @@ class EmailSender(object):
         )
         message.content_subtype = "html"
         message.send()
-
-# send_mail(subject, "", email_from, recipient_list, cc=cc_recipients, html_message=body)
+        logger.info('Email sent. Subject: ' + subject + "; Recipients: " + recipients)
diff --git a/smash/web/views/appointment.py b/smash/web/views/appointment.py
index a13e149e3c161a960b22c95ba4e1d3612840f40d..5f0e6d7d5265997afa2be09493ed84d3fc88a5ee 100644
--- a/smash/web/views/appointment.py
+++ b/smash/web/views/appointment.py
@@ -1,4 +1,5 @@
 # coding=utf-8
+import logging
 from django.contrib import messages
 from django.shortcuts import get_object_or_404, redirect
 
@@ -10,13 +11,14 @@ APPOINTMENT_LIST_GENERIC = "GENERIC"
 APPOINTMENT_LIST_UNFINISHED = "UNFINISHED"
 APPOINTMENT_LIST_APPROACHING = "APPROACHING"
 
+logger = logging.getLogger(__name__)
+
 
 def appointments(request):
     context = {
         'approaching_list': APPOINTMENT_LIST_APPROACHING,
         'full_list': APPOINTMENT_LIST_GENERIC
     }
-
     return wrap_response(request, "appointments/index.html", context)