diff --git a/Gemfile b/Gemfile
index cd4989cb68c523982b2aef95351fe6a710058531..d03a8ac4a4647dc903b78b3a6e9eff2d91a49189 100644
--- a/Gemfile
+++ b/Gemfile
@@ -64,4 +64,5 @@ end
 
 group :production do
   gem 'rails_12factor'
+  gem 'lograge'
 end
diff --git a/Gemfile.lock b/Gemfile.lock
index 1ff69cb710b0ee1e56a8d6047f6e9410a7c1b472..aab4ee335b67d1c522e8c8b82f4ebc9b4b4086fb 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -158,6 +158,10 @@ GEM
     letter_opener (1.4.1)
       launchy (~> 2.2)
     libv8 (3.16.14.15)
+    lograge (0.4.1)
+      actionpack (>= 4, < 5.1)
+      activesupport (>= 4, < 5.1)
+      railties (>= 4, < 5.1)
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
     mail (2.6.4)
@@ -377,6 +381,7 @@ DEPENDENCIES
   jbuilder (~> 2.0)
   jquery-rails
   letter_opener
+  lograge
   nokogiri
   oj
   onebox
diff --git a/app/assets/javascripts/components/components/media_gallery.jsx b/app/assets/javascripts/components/components/media_gallery.jsx
index 45d2f24920f313c1881a2faf082ed753475836f3..81bf7c87c7d790ce8aa254efef15a4b064ac7db5 100644
--- a/app/assets/javascripts/components/components/media_gallery.jsx
+++ b/app/assets/javascripts/components/components/media_gallery.jsx
@@ -59,7 +59,7 @@ const MediaGallery = React.createClass({
         }
       }
 
-      return <a key={attachment.get('id')} href={attachment.get('url')} style={{ boxSizing: 'border-box', position: 'relative', left: left, top: top, right: right, bottom: bottom, float: 'left', textDecoration: 'none', border: 'none', display: 'block', width: `${width}%`, height: `${height}%`, background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover', cursor: 'zoom-in' }} />;
+      return <a key={attachment.get('id')} href={attachment.get('url')} target='_blank' style={{ boxSizing: 'border-box', position: 'relative', left: left, top: top, right: right, bottom: bottom, float: 'left', textDecoration: 'none', border: 'none', display: 'block', width: `${width}%`, height: `${height}%`, background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover', cursor: 'zoom-in' }} />;
     });
 
     return (
diff --git a/app/assets/stylesheets/stream_entries.scss b/app/assets/stylesheets/stream_entries.scss
index 93880237c8f9930ef72566849b853532cc759a1b..25a536e246343588233d1392bd14126bd8a41b40 100644
--- a/app/assets/stylesheets/stream_entries.scss
+++ b/app/assets/stylesheets/stream_entries.scss
@@ -158,7 +158,7 @@
     font-size: 14px;
     padding: 0 10px;
     padding-left: 8px;
-    padding-bottom: 25px;
+    padding-bottom: 15px;
     color: #282c37;
 
     a {
@@ -189,4 +189,33 @@
       text-decoration: underline;
     }
   }
+
+  .media-attachments {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+    display: block;
+    overflow: hidden;
+    padding-left: 10px;
+
+    li {
+      display: block;
+      float: left;
+      width: 120px;
+      height: 100px;
+      border-radius: 4px;
+      margin-right: 4px;
+      margin-bottom: 25px;
+
+      a {
+        display: block;
+        width: 120px;
+        height: 100px;
+        border-radius: 4px;
+        background-position: center;
+        background-repeat: none;
+        background-size: cover;
+      }
+    }
+  }
 }
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 162e85dec0df84fb4da242747b5103baa3def04e..3c02e0becdfdc288bfc5ab66e092b0d8f0711f29 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -11,7 +11,7 @@ class AccountsController < ApplicationController
       format.atom do
         @entries = @account.stream_entries.order('id desc').with_includes.paginate_by_max_id(20, params[:max_id] || nil)
 
-        ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Status' }, activity: [:mentions, reblog: :account, thread: :account])
+        ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Status' }, activity: [:mentions, :media_attachments, reblog: :account, thread: :account])
         ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Favourite' }, activity: [:account, :status])
         ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Follow' }, activity: :target_account)
       end
diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml
index d210805fed7b5024dc96dc4b77a65773a96173b2..defadffc64cf609e9903f2b59ae2144304b3c826 100644
--- a/app/views/stream_entries/_status.html.haml
+++ b/app/views/stream_entries/_status.html.haml
@@ -38,6 +38,10 @@
 
       .content= content_for_status(proper_status(status))
 
+      %ul.media-attachments
+        - status.media_attachments.each do |media|
+          %li.transparent-background= link_to '', media.file.url, style: "background-image: url(#{media.file.url(:small)})", target: '_blank'
+
 - if include_threads
   - status.descendants.with_includes.with_counters.each do |status|
     = render partial: 'status', locals: { status: status, is_successor: true }
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 7322620cf6901e1091c89c4cc0bc562c23b25e6a..ee7598c4cc9eb6f03ec13815594886f3dd07dea7 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -64,6 +64,9 @@ Rails.application.configure do
   # Use default logging formatter so that PID and timestamp are not suppressed.
   config.log_formatter = ::Logger::Formatter.new
 
+  # Better log formatting
+  config.lograge.enabled = true
+
   # Do not dump schema after migrations.
   config.active_record.dump_schema_after_migration = false